Mesa (master): draw: finish the new pipeline setup

Zack Rusin zack at kemper.freedesktop.org
Tue Jun 15 06:12:30 PDT 2010


Module: Mesa
Branch: master
Commit: a192b5eeafae80f9f9e7e7e442abc5b44d583d1a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a192b5eeafae80f9f9e7e7e442abc5b44d583d1a

Author: Zack Rusin <zackr at vmware.com>
Date:   Tue Jun 15 08:05:51 2010 -0400

draw: finish the new pipeline setup

Keith came up with a new way of running the pipeline which involves passing
a few info structs around (for fetch, vertices and prims) and allows us
to correctly handle cases where we endup with multiple primitives generated
by the pipeline itself.

---

 src/gallium/auxiliary/draw/draw_gs.c               |   41 ++--
 src/gallium/auxiliary/draw/draw_gs.h               |    1 +
 src/gallium/auxiliary/draw/draw_gs_tmp.h           |   22 +-
 src/gallium/auxiliary/draw/draw_private.h          |    9 +-
 src/gallium/auxiliary/draw/draw_pt.h               |    4 +-
 .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c  |   41 ++-
 .../draw/draw_pt_fetch_shade_pipeline_llvm.c       |  292 ++++++++++----------
 src/gallium/auxiliary/draw/draw_pt_post_vs.c       |   54 ++---
 src/gallium/auxiliary/draw/draw_pt_so_emit.c       |   19 +-
 9 files changed, 238 insertions(+), 245 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index 787d93a..5d8fe10 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -171,9 +171,10 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
    /* Unswizzle all output results.
     */
 
-   shader->emitted_primitives += num_primitives;
    for (prim_idx = 0; prim_idx < num_primitives; ++prim_idx) {
       unsigned num_verts_per_prim = machine->Primitives[prim_idx];
+      shader->primitive_lengths[prim_idx +   shader->emitted_primitives] =
+         machine->Primitives[prim_idx];
       shader->emitted_vertices += num_verts_per_prim;
       for (j = 0; j < num_verts_per_prim; j++) {
          int idx = (prim_idx * num_verts_per_prim + j) *
@@ -199,6 +200,7 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
       }
    }
    *p_output = output;
+         shader->emitted_primitives += num_primitives;
 }
 
 
@@ -333,57 +335,60 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
                              struct draw_vertex_info *output_verts,
                              struct draw_prim_info *output_prims )
 {
-   const float (*input)[4] = input_verts->verts;
+   const float (*input)[4] = (const float (*)[4])input_verts->verts->data;
    unsigned input_stride = input_verts->vertex_size;
    unsigned vertex_size = input_verts->vertex_size;
    struct tgsi_exec_machine *machine = shader->machine;
    unsigned int i;
    unsigned num_in_primitives = u_gs_prims_for_vertices(input_prim->prim,
                                                         input_verts->count);
+   unsigned max_out_prims = u_gs_prims_for_vertices(shader->output_primitive,
+                                                    shader->max_output_vertices)
+                            * num_in_primitives;
 
    output_verts->vertex_size = input_verts->vertex_size;
    output_verts->stride = input_verts->vertex_size;
 
-   output_verts->count = draw_max_output_vertices(draw,
+   output_verts->count = draw_max_output_vertices(shader->draw,
                                                   input_prim->prim,
                                                   input_verts->count);
 
    output_verts->verts =
-         (struct vertex_header *)MALLOC(vert_info.vertex_size *
-                                        vert_info.count);
+      (struct vertex_header *)MALLOC(input_verts->vertex_size *
+                                     num_in_primitives *
+                                     shader->max_output_vertices);
 
 
 
    if (0) debug_printf("%s count = %d (prims = %d)\n", __FUNCTION__,
-                       count, num_in_primitives);
+                       input_verts->count, num_in_primitives);
 
    shader->emitted_vertices = 0;
    shader->emitted_primitives = 0;
    shader->vertex_size = vertex_size;
-   shader->tmp_output = (float (*)[4])input_verts->verts->data;
+   shader->tmp_output = (float (*)[4])output_verts->verts->data;
    shader->in_prim_idx = 0;
    shader->input_vertex_stride = input_stride;
    shader->input = input;
+   if (shader->primitive_lengths) {
+      FREE(shader->primitive_lengths);
+   }
+   shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned));
 
    for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
       machine->Consts[i] = constants[i];
    }
 
-   gs_run(shader, pipe_prim, count);
-
-   if (shader->emitted_vertices > 0) {
-      memcpy(output, pipeline_verts->data,
-             shader->info.num_outputs * 4 * sizeof(float) +
-             vertex_size * (shader->emitted_vertices -1));
-   }
+   gs_run(shader, input_prim, input_verts, output_prims, output_verts);
 
-   
-   /* Update prim_info: 
+   /* Update prim_info:
     */
    output_prims->linear = TRUE;
    output_prims->elts = NULL;
-   output_prims->primitive_lengths = machine->foo;
-   output_prims->primitive_count = machine->bar;
+   output_prims->start = 0;
+   output_prims->prim = shader->output_primitive;
+   output_prims->primitive_lengths = shader->primitive_lengths;
+   output_prims->primitive_count = shader->emitted_primitives;
 
    return shader->emitted_vertices;
 }
diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h
index 2374b12..2cb6348 100644
--- a/src/gallium/auxiliary/draw/draw_gs.h
+++ b/src/gallium/auxiliary/draw/draw_gs.h
@@ -54,6 +54,7 @@ struct draw_geometry_shader {
    unsigned input_primitive;
    unsigned output_primitive;
 
+   unsigned *primitive_lengths;
    unsigned emitted_vertices;
    unsigned emitted_primitives;
 
diff --git a/src/gallium/auxiliary/draw/draw_gs_tmp.h b/src/gallium/auxiliary/draw/draw_gs_tmp.h
index eb4a313..ded1c60 100644
--- a/src/gallium/auxiliary/draw/draw_gs_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_gs_tmp.h
@@ -1,18 +1,22 @@
 
 static void FUNC( struct draw_geometry_shader *shader,
-                  unsigned pipe_prim,
-                  unsigned count )
+                  const struct draw_prim_info *input_prims,
+                  const struct draw_vertex_info *input_verts,
+                  struct draw_prim_info *output_prims,
+                  struct draw_vertex_info *output_verts)
 {
    struct draw_context *draw = shader->draw;
 
    boolean flatfirst = (draw->rasterizer->flatshade &&
                         draw->rasterizer->flatshade_first);
    unsigned i;
+   unsigned count = input_prims->count;
 
    if (0) debug_printf("%s %d\n", __FUNCTION__, count);
 
+   debug_assert(input_prims->primitive_count == 1);
 
-   switch (pipe_prim) {
+   switch (input_prims->prim) {
    case PIPE_PRIM_POINTS:
       for (i = 0; i < count; i++) {
 	 POINT( shader, i + 0 );
@@ -93,16 +97,6 @@ static void FUNC( struct draw_geometry_shader *shader,
          /* These bitflags look a little odd because we submit the
           * vertices as (1,2,0) to satisfy flatshade requirements.
           */
-         ushort edge_next, edge_finish;
-
-         if (flatfirst) {
-            edge_next = DRAW_PIPE_EDGE_FLAG_2;
-            edge_finish = DRAW_PIPE_EDGE_FLAG_0;
-         }
-         else {
-            edge_next = DRAW_PIPE_EDGE_FLAG_0;
-            edge_finish = DRAW_PIPE_EDGE_FLAG_1;
-         }
 
 	 for (i = 0; i+2 < count; i++) {
 
@@ -117,7 +111,7 @@ static void FUNC( struct draw_geometry_shader *shader,
       break;
 
    default:
-      assert(0);
+      debug_assert(!"Unsupported primitive in geometry shader");
       break;
    }
 }
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index c6dc734..e9c9402 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -266,15 +266,11 @@ struct draw_context
 };
 
 
-
-
 struct draw_fetch_info {
    boolean linear;
    unsigned start;
-   void *elts;
+   const unsigned *elts;
    unsigned count;
-
-   
 };
 
 struct draw_vertex_info {
@@ -284,12 +280,11 @@ struct draw_vertex_info {
    unsigned count;
 };
 
-
 struct draw_prim_info {
    boolean linear;
    unsigned start;
 
-   ushort *elts;
+   const ushort *elts;
    unsigned count;
 
    unsigned prim;
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 821a73f..739420f 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -223,9 +223,7 @@ struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw );
 struct pt_post_vs;
 
 boolean draw_pt_post_vs_run( struct pt_post_vs *pvs,
-			     struct vertex_header *pipeline_verts,
-			     unsigned stride,
-			     unsigned count );
+			     struct draw_vertex_info *info );
 
 void draw_pt_post_vs_prepare( struct pt_post_vs *pvs,
 			      boolean bypass_clipping,
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index 4e39d55..599c495 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -139,7 +139,7 @@ static void fetch( struct pt_fetch *fetch,
    }
    else {
       draw_pt_fetch_run( fetch,
-                         fetch_info->elts, 
+                         fetch_info->elts,
                          fetch_info->count,
                          output );
    }
@@ -207,12 +207,14 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
    struct draw_vertex_info vs_vert_info;
    struct draw_vertex_info gs_vert_info;
    struct draw_vertex_info *vert_info;
+   unsigned opt = fpme->opt;
 
    fetched_vert_info.count = fetch_info->count;
    fetched_vert_info.vertex_size = fpme->vertex_size;
+   fetched_vert_info.stride = fpme->vertex_size;
    fetched_vert_info.verts =
-      (struct vertex_header *)MALLOC(fetched_vert_info.vertex_size *
-                                     fetch_info->count);
+      (struct vertex_header *)MALLOC(fpme->vertex_size *
+                                     align(fetch_info->count,  4));
    if (!fetched_vert_info.verts) {
       assert(0);
       return;
@@ -230,7 +232,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
    /* Run the shader, note that this overwrites the data[] parts of
     * the pipeline verts.
     */
-   if (fpme->opt & PT_SHADE) { 
+   if (fpme->opt & PT_SHADE) {
       draw_vertex_shader_run(vshader,
                              draw->pt.user.vs_constants,
                              vert_info,
@@ -247,8 +249,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
                                prim_info,
                                &gs_vert_info,
                                &gs_prim_info);
-         
-         
+
       FREE(vert_info->verts);
       vert_info = &gs_vert_info;
       prim_info = &gs_prim_info;
@@ -273,7 +274,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
    /* Do we need to run the pipeline?
     */
    if (opt & PT_PIPELINE) {
-      pipeline( fpme->draw,
+      pipeline( fpme,
                 vert_info,
                 prim_info );
    }
@@ -282,7 +283,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle,
             vert_info,
             prim_info );
    }
-
+   FREE(vert_info->verts);
 }
 
 static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
@@ -291,6 +292,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
                                 const ushort *draw_elts,
                                 unsigned draw_count )
 {
+   struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
    struct draw_fetch_info fetch_info;
    struct draw_prim_info prim_info;
 
@@ -303,6 +305,9 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
    prim_info.start = 0;
    prim_info.count = draw_count;
    prim_info.elts = draw_elts;
+   prim_info.prim = fpme->input_prim;
+   prim_info.primitive_count = 1;
+   prim_info.primitive_lengths = &draw_count;
 
    fetch_pipeline_generic( middle, &fetch_info, &prim_info );
 }
@@ -312,6 +317,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
                                        unsigned start,
                                        unsigned count)
 {
+   struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
    struct draw_fetch_info fetch_info;
    struct draw_prim_info prim_info;
 
@@ -324,6 +330,9 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
    prim_info.start = 0;
    prim_info.count = count;
    prim_info.elts = NULL;
+   prim_info.prim = fpme->input_prim;
+   prim_info.primitive_count = 1;
+   prim_info.primitive_lengths = &count;
 
    fetch_pipeline_generic( middle, &fetch_info, &prim_info );
 }
@@ -331,11 +340,12 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
 
 
 static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle,
-                                            unsigned start,
-                                            unsigned count,
-                                            const ushort *draw_elts,
-                                            unsigned draw_count )
+                                               unsigned start,
+                                               unsigned count,
+                                               const ushort *draw_elts,
+                                               unsigned draw_count )
 {
+   struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
    struct draw_fetch_info fetch_info;
    struct draw_prim_info prim_info;
 
@@ -348,8 +358,13 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
    prim_info.start = 0;
    prim_info.count = draw_count;
    prim_info.elts = draw_elts;
+   prim_info.prim = fpme->input_prim;
+   prim_info.primitive_count = 1;
+   prim_info.primitive_lengths = &draw_count;
 
    fetch_pipeline_generic( middle, &fetch_info, &prim_info );
+
+   return TRUE;
 }
 
 
@@ -403,7 +418,7 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context *
       goto fail;
 
    fpme->emit = draw_pt_emit_create( draw );
-   if (!fpme->emit) 
+   if (!fpme->emit)
       goto fail;
 
    fpme->so_emit = draw_pt_so_emit_create( draw );
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
index 5f6d238..65a9d4e 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
@@ -28,6 +28,7 @@
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "draw/draw_context.h"
+#include "draw/draw_gs.h"
 #include "draw/draw_vbuf.h"
 #include "draw/draw_vertex.h"
 #include "draw/draw_pt.h"
@@ -150,72 +151,142 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
 }
 
 
+static void pipeline(struct llvm_middle_end *llvm,
+                     const struct draw_vertex_info *vert_info,
+                     const struct draw_prim_info *prim_info)
+{
+   if (prim_info->linear)
+      draw_pipeline_run_linear( llvm->draw,
+                                vert_info,
+                                prim_info);
+   else
+      draw_pipeline_run( llvm->draw,
+                         vert_info,
+                         prim_info );
+}
 
-static void llvm_middle_end_run( struct draw_pt_middle_end *middle,
-                                 const unsigned *fetch_elts,
-                                 unsigned fetch_count,
-                                 const ushort *draw_elts,
-                                 unsigned draw_count )
+static void emit(struct pt_emit *emit,
+                 const struct draw_vertex_info *vert_info,
+                 const struct draw_prim_info *prim_info)
+{
+   if (prim_info->linear) {
+      draw_pt_emit_linear(emit, vert_info, prim_info);
+   }
+   else {
+      draw_pt_emit(emit, vert_info, prim_info);
+   }
+}
+
+static void
+llvm_pipeline_generic( struct draw_pt_middle_end *middle,
+                       const struct draw_fetch_info *fetch_info,
+                       const struct draw_prim_info *prim_info )
 {
    struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
    struct draw_context *draw = fpme->draw;
+   struct draw_geometry_shader *gshader = draw->gs.geometry_shader;
+   struct draw_prim_info gs_prim_info;
+   struct draw_vertex_info llvm_vert_info;
+   struct draw_vertex_info gs_vert_info;
+   struct draw_vertex_info *vert_info;
    unsigned opt = fpme->opt;
-   unsigned alloc_count = align( fetch_count, 4 );
 
-   struct vertex_header *pipeline_verts =
-      (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
-
-   if (!pipeline_verts) {
-      /* Not much we can do here - just skip the rendering.
-       */
+   llvm_vert_info.count = fetch_info->count;
+   llvm_vert_info.vertex_size = fpme->vertex_size;
+   llvm_vert_info.stride = fpme->vertex_size;
+   llvm_vert_info.verts =
+      (struct vertex_header *)MALLOC(fpme->vertex_size *
+                                     align(fetch_info->count,  4));
+   if (!llvm_vert_info.verts) {
       assert(0);
       return;
    }
 
-   fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context,
-                                         pipeline_verts,
-                                         (const char **)draw->pt.user.vbuffer,
-                                         fetch_elts,
-                                         fetch_count,
-                                         fpme->vertex_size,
-                                         draw->pt.vertex_buffer );
+   if (fetch_info->linear)
+      fpme->current_variant->jit_func( &fpme->llvm->jit_context,
+                                       llvm_vert_info.verts,
+                                       (const char **)draw->pt.user.vbuffer,
+                                       fetch_info->start,
+                                       fetch_info->count,
+                                       fpme->vertex_size,
+                                       draw->pt.vertex_buffer );
+   else
+      fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context,
+                                            llvm_vert_info.verts,
+                                            (const char **)draw->pt.user.vbuffer,
+                                            fetch_info->elts,
+                                            fetch_info->count,
+                                            fpme->vertex_size,
+                                            draw->pt.vertex_buffer);
+
+   /* Finished with fetch and vs:
+    */
+   fetch_info = NULL;
+   vert_info = &llvm_vert_info;
+
+
+   if ((opt & PT_SHADE) && gshader) {
+      draw_geometry_shader_run(gshader,
+                               draw->pt.user.gs_constants,
+                               vert_info,
+                               prim_info,
+                               &gs_vert_info,
+                               &gs_prim_info);
+
+      FREE(vert_info->verts);
+      vert_info = &gs_vert_info;
+      prim_info = &gs_prim_info;
+   }
 
    /* stream output needs to be done before clipping */
    draw_pt_so_emit( fpme->so_emit,
-		    (const float (*)[4])pipeline_verts->data,
-		    fetch_count,
-		    fpme->vertex_size );
-
-   if (draw_pt_post_vs_run( fpme->post_vs,
-			    pipeline_verts,
-			    fetch_count,
-			    fpme->vertex_size ))
-   {
+		    vert_info,
+                    prim_info );
+
+   if (draw_pt_post_vs_run( fpme->post_vs, vert_info )) {
       opt |= PT_PIPELINE;
    }
 
    /* Do we need to run the pipeline?
     */
    if (opt & PT_PIPELINE) {
-      draw_pipeline_run( fpme->draw,
-                         fpme->output_prim,
-                         pipeline_verts,
-                         fetch_count,
-                         fpme->vertex_size,
-                         draw_elts,
-                         draw_count );
+      pipeline( fpme,
+                vert_info,
+                prim_info );
    }
    else {
-      draw_pt_emit( fpme->emit,
-		    (const float (*)[4])pipeline_verts->data,
-		    fetch_count,
-		    fpme->vertex_size,
-		    draw_elts,
-		    draw_count );
+      emit( fpme->emit,
+            vert_info,
+            prim_info );
    }
+   FREE(vert_info->verts);
+}
 
 
-   FREE(pipeline_verts);
+static void llvm_middle_end_run( struct draw_pt_middle_end *middle,
+                                 const unsigned *fetch_elts,
+                                 unsigned fetch_count,
+                                 const ushort *draw_elts,
+                                 unsigned draw_count )
+{
+   struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
+   struct draw_fetch_info fetch_info;
+   struct draw_prim_info prim_info;
+
+   fetch_info.linear = FALSE;
+   fetch_info.start = 0;
+   fetch_info.elts = fetch_elts;
+   fetch_info.count = fetch_count;
+
+   prim_info.linear = FALSE;
+   prim_info.start = 0;
+   prim_info.count = draw_count;
+   prim_info.elts = draw_elts;
+   prim_info.prim = fpme->input_prim;
+   prim_info.primitive_count = 1;
+   prim_info.primitive_lengths = &draw_count;
+
+   llvm_pipeline_generic( middle, &fetch_info, &prim_info );
 }
 
 
@@ -224,63 +295,23 @@ static void llvm_middle_end_linear_run( struct draw_pt_middle_end *middle,
                                        unsigned count)
 {
    struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
-   struct draw_context *draw = fpme->draw;
-   unsigned opt = fpme->opt;
-   unsigned alloc_count = align( count, 4 );
-
-   struct vertex_header *pipeline_verts =
-      (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
-
-   if (!pipeline_verts) {
-      /* Not much we can do here - just skip the rendering.
-       */
-      assert(0);
-      return;
-   }
-
-#if 0
-   debug_printf("#### Pipeline = %p (data = %p)\n",
-                pipeline_verts, pipeline_verts->data);
-#endif
-   fpme->current_variant->jit_func( &fpme->llvm->jit_context,
-                                    pipeline_verts,
-                                    (const char **)draw->pt.user.vbuffer,
-                                    start,
-                                    count,
-                                    fpme->vertex_size,
-                                    draw->pt.vertex_buffer );
-
-   /* stream output needs to be done before clipping */
-   draw_pt_so_emit( fpme->so_emit,
-		    (const float (*)[4])pipeline_verts->data,
-		    count,
-		    fpme->vertex_size );
-
-   if (draw_pt_post_vs_run( fpme->post_vs,
-			    pipeline_verts,
-			    count,
-			    fpme->vertex_size ))
-   {
-      opt |= PT_PIPELINE;
-   }
-
-   /* Do we need to run the pipeline?
-    */
-   if (opt & PT_PIPELINE) {
-      draw_pipeline_run_linear( fpme->draw,
-                                fpme->output_prim,
-                                pipeline_verts,
-                                count,
-                                fpme->vertex_size);
-   }
-   else {
-      draw_pt_emit_linear( fpme->emit,
-                           (const float (*)[4])pipeline_verts->data,
-                           fpme->vertex_size,
-                           count );
-   }
-
-   FREE(pipeline_verts);
+   struct draw_fetch_info fetch_info;
+   struct draw_prim_info prim_info;
+
+   fetch_info.linear = TRUE;
+   fetch_info.start = start;
+   fetch_info.count = count;
+   fetch_info.elts = NULL;
+
+   prim_info.linear = TRUE;
+   prim_info.start = 0;
+   prim_info.count = count;
+   prim_info.elts = NULL;
+   prim_info.prim = fpme->input_prim;
+   prim_info.primitive_count = 1;
+   prim_info.primitive_lengths = &count;
+
+   llvm_pipeline_generic( middle, &fetch_info, &prim_info );
 }
 
 
@@ -293,59 +324,24 @@ llvm_middle_end_linear_run_elts( struct draw_pt_middle_end *middle,
                                  unsigned draw_count )
 {
    struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
-   struct draw_context *draw = fpme->draw;
-   unsigned opt = fpme->opt;
-   unsigned alloc_count = align( count, 4 );
+   struct draw_fetch_info fetch_info;
+   struct draw_prim_info prim_info;
 
-   struct vertex_header *pipeline_verts =
-      (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
+   fetch_info.linear = TRUE;
+   fetch_info.start = start;
+   fetch_info.count = count;
+   fetch_info.elts = NULL;
 
-   if (!pipeline_verts)
-      return FALSE;
-
-   fpme->current_variant->jit_func( &fpme->llvm->jit_context,
-                                    pipeline_verts,
-                                    (const char **)draw->pt.user.vbuffer,
-                                    start,
-                                    count,
-                                    fpme->vertex_size,
-                                    draw->pt.vertex_buffer );
-
-   /* stream output needs to be done before clipping */
-   draw_pt_so_emit( fpme->so_emit,
-		    (const float (*)[4])pipeline_verts->data,
-		    count,
-		    fpme->vertex_size );
-
-   if (draw_pt_post_vs_run( fpme->post_vs,
-			    pipeline_verts,
-			    count,
-			    fpme->vertex_size ))
-   {
-      opt |= PT_PIPELINE;
-   }
+   prim_info.linear = FALSE;
+   prim_info.start = 0;
+   prim_info.count = draw_count;
+   prim_info.elts = draw_elts;
+   prim_info.prim = fpme->input_prim;
+   prim_info.primitive_count = 1;
+   prim_info.primitive_lengths = &draw_count;
 
-   /* Do we need to run the pipeline?
-    */
-   if (opt & PT_PIPELINE) {
-      draw_pipeline_run( fpme->draw,
-                         fpme->output_prim,
-                         pipeline_verts,
-                         count,
-                         fpme->vertex_size,
-                         draw_elts,
-                         draw_count );
-   }
-   else {
-      draw_pt_emit( fpme->emit,
-		    (const float (*)[4])pipeline_verts->data,
-		    count,
-		    fpme->vertex_size,
-		    draw_elts,
-		    draw_count );
-   }
+   llvm_pipeline_generic( middle, &fetch_info, &prim_info );
 
-   FREE(pipeline_verts);
    return TRUE;
 }
 
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index fd33a54..1000cc5 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -36,9 +36,7 @@ struct pt_post_vs {
    struct draw_context *draw;
 
    boolean (*run)( struct pt_post_vs *pvs,
-		struct vertex_header *vertices,
-		unsigned count,
-		unsigned stride );
+                   struct draw_vertex_info *info );
 };
 
 
@@ -92,20 +90,18 @@ compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr)
  * instructions
  */
 static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
-					  struct vertex_header *vertices,
-					  unsigned count,
-					  unsigned stride )
+                                             struct draw_vertex_info *info )
 {
-   struct vertex_header *out = vertices;
+   struct vertex_header *out = info->verts;
    const float *scale = pvs->draw->viewport.scale;
    const float *trans = pvs->draw->viewport.translate;
    const unsigned pos = draw_current_shader_position_output(pvs->draw);
    unsigned clipped = 0;
    unsigned j;
 
-   if (0) debug_printf("%s count, %d\n", __FUNCTION__, count);
+   if (0) debug_printf("%s count, %d\n", __FUNCTION__, info->count);
 
-   for (j = 0; j < count; j++) {
+   for (j = 0; j < info->count; j++) {
       float *position = out->data[pos];
 
 #if 0
@@ -143,7 +139,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
 #endif
       }
 
-      out = (struct vertex_header *)( (char *)out + stride );
+      out = (struct vertex_header *)( (char *)out + info->stride );
    }
 
    return clipped != 0;
@@ -153,29 +149,27 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
 
 /* As above plus edgeflags
  */
-static boolean 
+static boolean
 post_vs_cliptest_viewport_gl_edgeflag(struct pt_post_vs *pvs,
-                                      struct vertex_header *vertices,
-                                      unsigned count,
-                                      unsigned stride )
+                                      struct draw_vertex_info *info)
 {
    unsigned j;
    boolean needpipe;
 
-   needpipe = post_vs_cliptest_viewport_gl( pvs, vertices, count, stride);
+   needpipe = post_vs_cliptest_viewport_gl(pvs, info);
 
    /* If present, copy edgeflag VS output into vertex header.
     * Otherwise, leave header as is.
     */
    if (pvs->draw->vs.edgeflag_output) {
-      struct vertex_header *out = vertices;
+      struct vertex_header *out = info->verts;
       int ef = pvs->draw->vs.edgeflag_output;
 
-      for (j = 0; j < count; j++) {
+      for (j = 0; j < info->count; j++) {
          const float *edgeflag = out->data[ef];
          out->edgeflag = !(edgeflag[0] != 1.0f);
          needpipe |= !out->edgeflag;
-         out = (struct vertex_header *)( (char *)out + stride );
+         out = (struct vertex_header *)( (char *)out + info->stride );
       }
    }
    return needpipe;
@@ -187,18 +181,16 @@ post_vs_cliptest_viewport_gl_edgeflag(struct pt_post_vs *pvs,
 /* If bypass_clipping is set, skip cliptest and rhw divide.
  */
 static boolean post_vs_viewport( struct pt_post_vs *pvs,
-			      struct vertex_header *vertices,
-			      unsigned count,
-			      unsigned stride )
+                                 struct draw_vertex_info *info )
 {
-   struct vertex_header *out = vertices;
+   struct vertex_header *out = info->verts;
    const float *scale = pvs->draw->viewport.scale;
    const float *trans = pvs->draw->viewport.translate;
    const unsigned pos = draw_current_shader_position_output(pvs->draw);
    unsigned j;
 
    if (0) debug_printf("%s\n", __FUNCTION__);
-   for (j = 0; j < count; j++) {
+   for (j = 0; j < info->count; j++) {
       float *position = out->data[pos];
 
       /* Viewport mapping only, no cliptest/rhw divide
@@ -207,9 +199,9 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs,
       position[1] = position[1] * scale[1] + trans[1];
       position[2] = position[2] * scale[2] + trans[2];
 
-      out = (struct vertex_header *)((char *)out + stride);
+      out = (struct vertex_header *)((char *)out + info->stride);
    }
-   
+
    return FALSE;
 }
 
@@ -218,20 +210,16 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs,
  * to do.
  */
 static boolean post_vs_none( struct pt_post_vs *pvs,
-			     struct vertex_header *vertices,
-			     unsigned count,
-			     unsigned stride )
+			     struct draw_vertex_info *info )
 {
    if (0) debug_printf("%s\n", __FUNCTION__);
    return FALSE;
 }
 
 boolean draw_pt_post_vs_run( struct pt_post_vs *pvs,
-			     struct vertex_header *pipeline_verts,
-			     unsigned count,
-			     unsigned stride )
+			     struct draw_vertex_info *info )
 {
-   return pvs->run( pvs, pipeline_verts, count, stride );
+   return pvs->run( pvs, info );
 }
 
 
@@ -272,7 +260,7 @@ struct pt_post_vs *draw_pt_post_vs_create( struct draw_context *draw )
       return NULL;
 
    pvs->draw = draw;
-   
+
    return pvs;
 }
 
diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
index 2bdfef1..f5abb79 100644
--- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
@@ -136,13 +136,14 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
                       const struct draw_vertex_info *vert_info,
                       const struct draw_prim_info *prim_info )
 {
-   const float (*vertex_data)[4] = vert_info->verts;
+   const float (*vertex_data)[4] = (const float (*)[4])vert_info->verts->data;
    unsigned vertex_count = vert_info->count;
    unsigned stride = vert_info->stride;
    struct draw_context *draw = emit->draw;
    struct translate *translate = emit->translate;
    struct vbuf_render *render = draw->render;
    void *so_buffer;
+   unsigned start, i;
 
    if (!emit->has_so)
       return;
@@ -168,20 +169,20 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
 
    translate->set_buffer(translate, 0, vertex_data,
                          stride, ~0);
-   
-   for (start = i = 0;
-        i < prim_info->primitive_count;
+
+   for (start = i = 0; i < prim_info->primitive_count;
         start += prim_info->primitive_lengths[i], i++)
    {
       unsigned count = prim_info->primitive_lengths[i];
-      
+
       if (prim_info->linear) {
-         translate->runXXX(translate, start, count,
-                           draw->instance_id, so_buffer);
+         translate->run(translate, start, count,
+                        draw->instance_id, so_buffer);
       }
       else {
-         translate->runYYY(translate, start, count,
-                           draw->instance_id, so_buffer);
+         debug_assert(!"Stream output can't handle non-linear prims yet");
+         translate->run(translate, start, count,
+                        draw->instance_id, so_buffer);
       }
    }
 



More information about the mesa-commit mailing list