Mesa (master): geometry shaders: make gs work with changable primitives and variable number of vertices

Zack Rusin zack at kemper.freedesktop.org
Wed Jun 9 08:15:02 PDT 2010


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

Author: Zack Rusin <zack at kde.org>
Date:   Wed Jun  9 11:13:34 2010 -0400

geometry shaders: make gs work with changable primitives and variable number of vertices

lots and lots of fixes for geometry shaders. in particular now we work when the gs
emits a different primitive than the one the pipeline was started with and also
we work when gs emits more vertices than would fit in the original buffer.

---

 src/gallium/auxiliary/draw/draw_gs.c               |   25 ++++--
 src/gallium/auxiliary/draw/draw_gs.h               |   22 +++--
 src/gallium/auxiliary/draw/draw_pt.c               |   19 +++--
 src/gallium/auxiliary/draw/draw_pt.h               |    6 +-
 src/gallium/auxiliary/draw/draw_pt_fetch_emit.c    |    3 +-
 .../auxiliary/draw/draw_pt_fetch_shade_emit.c      |   11 +--
 .../auxiliary/draw/draw_pt_fetch_shade_pipeline.c  |   91 ++++++++++++--------
 .../draw/draw_pt_fetch_shade_pipeline_llvm.c       |   19 +++--
 src/gallium/auxiliary/draw/draw_pt_post_vs.c       |    2 +-
 src/gallium/auxiliary/draw/draw_pt_varray.c        |   10 ++-
 src/gallium/auxiliary/draw/draw_pt_vcache.c        |   36 +++++----
 src/gallium/auxiliary/tgsi/tgsi_ureg.c             |    2 +-
 src/gallium/include/pipe/p_shader_tokens.h         |    2 +-
 src/gallium/tests/graw/geometry-shader/line.txt    |    3 +-
 14 files changed, 152 insertions(+), 99 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index 131deed..4034bd4 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -112,7 +112,7 @@ draw_create_geometry_shader(struct draw_context *draw,
                TGSI_PROPERTY_GS_OUTPUT_PRIM)
          gs->output_primitive = gs->info.properties[i].data[0];
       else if (gs->info.properties[i].name ==
-               TGSI_PROPERTY_GS_MAX_VERTICES)
+               TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES)
          gs->max_output_vertices = gs->info.properties[i].data[0];
    }
 
@@ -247,7 +247,7 @@ static void draw_fetch_geometry_input(struct draw_geometry_shader *shader,
       }
    }
 }
-
+/*#define DEBUG_OUTPUTS 1*/
 static INLINE void
 draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
                             int num_primitives,
@@ -263,8 +263,11 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
     * the first one
     unsigned prim_count =
     mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];*/
+
+   shader->emitted_primitives += num_primitives;
    for (prim_idx = 0; prim_idx < num_primitives; ++prim_idx) {
       unsigned num_verts_per_prim = machine->Primitives[0];
+      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) *
                    shader->info.num_outputs;
@@ -290,13 +293,13 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
    }
 }
 
-void draw_geometry_shader_run(struct draw_geometry_shader *shader,
-                              const float (*input)[4],
-                              float (*output)[4],
-                              const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
-                              unsigned count,
-                              unsigned input_stride,
-                              unsigned vertex_size)
+int draw_geometry_shader_run(struct draw_geometry_shader *shader,
+                             const float (*input)[4],
+                             float (*output)[4],
+                             const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+                             unsigned count,
+                             unsigned input_stride,
+                             unsigned vertex_size)
 {
    struct tgsi_exec_machine *machine = shader->machine;
    unsigned int i;
@@ -304,6 +307,9 @@ void draw_geometry_shader_run(struct draw_geometry_shader *shader,
    unsigned num_primitives = count/num_vertices;
    unsigned inputs_from_vs = 0;
 
+   shader->emitted_vertices = 0;
+   shader->emitted_primitives = 0;
+
    for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
       machine->Consts[i] = constants[i];
    }
@@ -331,6 +337,7 @@ void draw_geometry_shader_run(struct draw_geometry_shader *shader,
       draw_geometry_fetch_outputs(shader, max_primitives,
                                   output, vertex_size);
    }
+   return shader->emitted_vertices;
 }
 
 void draw_geometry_shader_delete(struct draw_geometry_shader *shader)
diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h
index d8eb210..6a9800c 100644
--- a/src/gallium/auxiliary/draw/draw_gs.h
+++ b/src/gallium/auxiliary/draw/draw_gs.h
@@ -54,18 +54,26 @@ struct draw_geometry_shader {
    unsigned input_primitive;
    unsigned output_primitive;
 
+   unsigned emitted_vertices;
+   unsigned emitted_primitives;
+
    /* Extracted from shader:
     */
    const float (*immediates)[4];
 };
 
-void draw_geometry_shader_run(struct draw_geometry_shader *shader,
-                              const float (*input)[4],
-                              float (*output)[4],
-                              const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
-                              unsigned count,
-                              unsigned input_stride,
-                              unsigned output_stride);
+/*
+ * Returns the number of vertices emitted.
+ * The vertex shader can emit any number of vertices as long as it's
+ * smaller than the GS_MAX_OUTPUT_VERTICES shader property.
+ */
+int draw_geometry_shader_run(struct draw_geometry_shader *shader,
+                             const float (*input)[4],
+                             float (*output)[4],
+                             const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+                             unsigned count,
+                             unsigned input_stride,
+                             unsigned output_stride);
 
 void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
                                   struct draw_context *draw);
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index c7eb156..02c97fe 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -31,6 +31,7 @@
   */
 
 #include "draw/draw_context.h"
+#include "draw/draw_gs.h"
 #include "draw/draw_private.h"
 #include "draw/draw_pt.h"
 #include "tgsi/tgsi_dump.h"
@@ -68,35 +69,39 @@ draw_pt_arrays(struct draw_context *draw,
    struct draw_pt_front_end *frontend = NULL;
    struct draw_pt_middle_end *middle = NULL;
    unsigned opt = 0;
+   unsigned out_prim = prim;
 
    /* Sanitize primitive length:
     */
    {
       unsigned first, incr;
       draw_pt_split_prim(prim, &first, &incr);
-      count = trim(count, first, incr); 
+      count = trim(count, first, incr);
       if (count < first)
          return TRUE;
    }
+   if (draw->gs.geometry_shader) {
+      out_prim = draw->gs.geometry_shader->output_primitive;
+   }
 
    if (!draw->force_passthrough) {
       if (!draw->render) {
          opt |= PT_PIPELINE;
       }
-      
+
       if (draw_need_pipeline(draw,
                              draw->rasterizer,
-                             prim)) {
+                             out_prim)) {
          opt |= PT_PIPELINE;
       }
 
       if (!draw->bypass_clipping && !draw->pt.test_fse) {
          opt |= PT_CLIPTEST;
       }
-      
+
       opt |= PT_SHADE;
    }
-      
+
    if (draw->pt.middle.llvm && !draw->gs.geometry_shader) {
       middle = draw->pt.middle.llvm;
    } else {
@@ -117,9 +122,9 @@ draw_pt_arrays(struct draw_context *draw,
       frontend = draw->pt.front.varray;
    }
 
-   frontend->prepare( frontend, prim, middle, opt );
+   frontend->prepare( frontend, prim, out_prim, middle, opt );
 
-   frontend->run(frontend, 
+   frontend->run(frontend,
                  draw_pt_elt_func(draw),
                  draw_pt_elt_ptr(draw, start),
                  draw->pt.user.eltBias,
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index b903246..67ae70f 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -60,7 +60,8 @@ struct draw_context;
  */
 struct draw_pt_front_end {
    void (*prepare)( struct draw_pt_front_end *,
-                    unsigned prim,
+                    unsigned input_prim,
+                    unsigned output_prim,
                     struct draw_pt_middle_end *,
 		    unsigned opt );
 
@@ -84,7 +85,8 @@ struct draw_pt_front_end {
  */
 struct draw_pt_middle_end {
    void (*prepare)( struct draw_pt_middle_end *,
-                    unsigned prim,
+                    unsigned input_prim,
+                    unsigned output_prim,
 		    unsigned opt,
                     unsigned *max_vertices );
 
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 5158c63..c629d55 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -90,6 +90,7 @@ struct fetch_emit_middle_end {
 
 static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
                                 unsigned prim,
+                                unsigned out_prim,
 				unsigned opt,
                                 unsigned *max_vertices )
 {
@@ -102,7 +103,7 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
 
 
    ok = draw->render->set_primitive( draw->render, 
-                                     prim );
+                                     out_prim );
    if (!ok) {
       assert(0);
       return;
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
index f0fc591..5483a25 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
@@ -67,9 +67,9 @@ struct fetch_shade_emit {
 
 
 
-			       
 static void fse_prepare( struct draw_pt_middle_end *middle,
-                         unsigned prim, 
+                         unsigned in_prim,
+                         unsigned out_prim,
                          unsigned opt,
                          unsigned *max_vertices )
 {
@@ -79,10 +79,10 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
    const struct vertex_info *vinfo;
    unsigned i;
    unsigned nr_vbs = 0;
-   
 
-   if (!draw->render->set_primitive( draw->render, 
-                                     prim )) {
+
+   if (!draw->render->set_primitive( draw->render,
+                                     out_prim )) {
       assert(0);
       return;
    }
@@ -90,7 +90,6 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
    /* Must do this after set_primitive() above:
     */
    fse->vinfo = vinfo = draw->render->get_vertex_info(draw->render);
-   
 
 
    fse->key.output_stride = vinfo->size * 4;
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 0d15ba2..afc146c 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -46,13 +46,15 @@ struct fetch_pipeline_middle_end {
 
    unsigned vertex_data_offset;
    unsigned vertex_size;
-   unsigned prim;
+   unsigned input_prim;
+   unsigned output_prim;
    unsigned opt;
 };
 
 
 static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
-                                    unsigned prim,
+                                    unsigned in_prim,
+                                    unsigned out_prim,
 				    unsigned opt,
                                     unsigned *max_vertices )
 {
@@ -77,7 +79,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
       }
    }
 
-   fpme->prim = prim;
+   fpme->input_prim = in_prim;
+   fpme->output_prim = out_prim;
    fpme->opt = opt;
 
    /* Always leave room for the vertex header whether we need it or
@@ -99,13 +102,13 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
 			    (boolean)draw->bypass_clipping,
 			    (boolean)draw->identity_viewport,
 			    (boolean)draw->rasterizer->gl_rasterization_rules,
-			    (draw->vs.edgeflag_output ? true : false) );    
+			    (draw->vs.edgeflag_output ? true : false) );
 
-   draw_pt_so_emit_prepare( fpme->so_emit, prim );
+   draw_pt_so_emit_prepare( fpme->so_emit, out_prim );
 
    if (!(opt & PT_PIPELINE)) {
-      draw_pt_emit_prepare( fpme->emit, 
-			    prim,
+      draw_pt_emit_prepare( fpme->emit,
+			    out_prim,
                             max_vertices );
 
       *max_vertices = MAX2( *max_vertices,
@@ -136,9 +139,15 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
    struct draw_vertex_shader *vshader = draw->vs.vertex_shader;
    struct draw_geometry_shader *gshader = draw->gs.geometry_shader;
    unsigned opt = fpme->opt;
+   struct vertex_header *pipeline_verts;
    unsigned alloc_count = align( fetch_count, 4 );
 
-   struct vertex_header *pipeline_verts = 
+   if (draw->gs.geometry_shader &&
+       draw->gs.geometry_shader->max_output_vertices > fetch_count) {
+      alloc_count = align(draw->gs.geometry_shader->max_output_vertices, 4);
+   }
+
+   pipeline_verts =
       (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
 
    if (!pipeline_verts) {
@@ -168,13 +177,14 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
                           fpme->vertex_size,
                           fpme->vertex_size);
       if (gshader)
-         draw_geometry_shader_run(gshader,
-                                  (const float (*)[4])pipeline_verts->data,
-                                  (      float (*)[4])pipeline_verts->data,
-                                  draw->pt.user.gs_constants,
-                                  fetch_count,
-                                  fpme->vertex_size,
-                                  fpme->vertex_size);
+         fetch_count =
+            draw_geometry_shader_run(gshader,
+                                     (const float (*)[4])pipeline_verts->data,
+                                     (      float (*)[4])pipeline_verts->data,
+                                     draw->pt.user.gs_constants,
+                                     fetch_count,
+                                     fpme->vertex_size,
+                                     fpme->vertex_size);
    }
 
    /* stream output needs to be done before clipping */
@@ -195,7 +205,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
     */
    if (opt & PT_PIPELINE) {
       draw_pipeline_run( fpme->draw,
-                         fpme->prim,
+                         fpme->output_prim,
                          pipeline_verts,
                          fetch_count,
                          fpme->vertex_size,
@@ -225,9 +235,14 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
    struct draw_vertex_shader *shader = draw->vs.vertex_shader;
    struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader;
    unsigned opt = fpme->opt;
+   struct vertex_header *pipeline_verts;
    unsigned alloc_count = align( count, 4 );
 
-   struct vertex_header *pipeline_verts =
+   if (geometry_shader && geometry_shader->max_output_vertices > count) {
+      alloc_count = align(geometry_shader->max_output_vertices, 4);
+   }
+
+   pipeline_verts =
       (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
 
    if (!pipeline_verts) {
@@ -258,13 +273,13 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
 			 fpme->vertex_size);
 
       if (geometry_shader)
-         draw_geometry_shader_run(geometry_shader,
-                                  (const float (*)[4])pipeline_verts->data,
-                                  (      float (*)[4])pipeline_verts->data,
-                                  draw->pt.user.gs_constants,
-                                  count,
-                                  fpme->vertex_size,
-                                  fpme->vertex_size);
+         count = draw_geometry_shader_run(geometry_shader,
+                                          (const float (*)[4])pipeline_verts->data,
+                                          (      float (*)[4])pipeline_verts->data,
+                                          draw->pt.user.gs_constants,
+                                          count,
+                                          fpme->vertex_size,
+                                          fpme->vertex_size);
    }
 
    /* stream output needs to be done before clipping */
@@ -285,7 +300,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
     */
    if (opt & PT_PIPELINE) {
       draw_pipeline_run_linear( fpme->draw,
-                                fpme->prim,
+                                fpme->output_prim,
                                 pipeline_verts,
                                 count,
                                 fpme->vertex_size);
@@ -313,12 +328,18 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
    struct draw_vertex_shader *shader = draw->vs.vertex_shader;
    struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader;
    unsigned opt = fpme->opt;
+   struct vertex_header *pipeline_verts;
    unsigned alloc_count = align( count, 4 );
 
-   struct vertex_header *pipeline_verts =
+   if (draw->gs.geometry_shader &&
+       draw->gs.geometry_shader->max_output_vertices > count) {
+      alloc_count = align(draw->gs.geometry_shader->max_output_vertices, 4);
+   }
+
+   pipeline_verts =
       (struct vertex_header *)MALLOC(fpme->vertex_size * alloc_count);
 
-   if (!pipeline_verts) 
+   if (!pipeline_verts)
       return FALSE;
 
    /* Fetch into our vertex buffer
@@ -342,13 +363,13 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
 			 fpme->vertex_size);
 
       if (geometry_shader)
-         draw_geometry_shader_run(geometry_shader,
-                                  (const float (*)[4])pipeline_verts->data,
-                                  (      float (*)[4])pipeline_verts->data,
-                                  draw->pt.user.gs_constants,
-                                  count,
-                                  fpme->vertex_size,
-                                  fpme->vertex_size);
+         count = draw_geometry_shader_run(geometry_shader,
+                                          (const float (*)[4])pipeline_verts->data,
+                                          (      float (*)[4])pipeline_verts->data,
+                                          draw->pt.user.gs_constants,
+                                          count,
+                                          fpme->vertex_size,
+                                          fpme->vertex_size);
    }
 
    /* stream output needs to be done before clipping */
@@ -369,7 +390,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
     */
    if (opt & PT_PIPELINE) {
       draw_pipeline_run( fpme->draw,
-                         fpme->prim,
+                         fpme->output_prim,
                          pipeline_verts,
                          count,
                          fpme->vertex_size,
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 584a1a5..5f6d238 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
@@ -47,7 +47,8 @@ struct llvm_middle_end {
 
    unsigned vertex_data_offset;
    unsigned vertex_size;
-   unsigned prim;
+   unsigned input_prim;
+   unsigned output_prim;
    unsigned opt;
 
    struct draw_llvm *llvm;
@@ -59,7 +60,8 @@ struct llvm_middle_end {
 
 static void
 llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
-                         unsigned prim,
+                         unsigned in_prim,
+                         unsigned out_prim,
                          unsigned opt,
                          unsigned *max_vertices )
 {
@@ -86,7 +88,8 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
       }
    }
 
-   fpme->prim = prim;
+   fpme->input_prim = in_prim;
+   fpme->output_prim = out_prim;
    fpme->opt = opt;
 
    /* Always leave room for the vertex header whether we need it or
@@ -105,10 +108,10 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
 			    (boolean)draw->rasterizer->gl_rasterization_rules,
 			    (draw->vs.edgeflag_output ? true : false) );
 
-   draw_pt_so_emit_prepare( fpme->so_emit, prim );
+   draw_pt_so_emit_prepare( fpme->so_emit, out_prim );
    if (!(opt & PT_PIPELINE)) {
       draw_pt_emit_prepare( fpme->emit,
-			    prim,
+			    out_prim,
                             max_vertices );
 
       *max_vertices = MAX2( *max_vertices,
@@ -195,7 +198,7 @@ static void llvm_middle_end_run( struct draw_pt_middle_end *middle,
     */
    if (opt & PT_PIPELINE) {
       draw_pipeline_run( fpme->draw,
-                         fpme->prim,
+                         fpme->output_prim,
                          pipeline_verts,
                          fetch_count,
                          fpme->vertex_size,
@@ -265,7 +268,7 @@ static void llvm_middle_end_linear_run( struct draw_pt_middle_end *middle,
     */
    if (opt & PT_PIPELINE) {
       draw_pipeline_run_linear( fpme->draw,
-                                fpme->prim,
+                                fpme->output_prim,
                                 pipeline_verts,
                                 count,
                                 fpme->vertex_size);
@@ -326,7 +329,7 @@ llvm_middle_end_linear_run_elts( struct draw_pt_middle_end *middle,
     */
    if (opt & PT_PIPELINE) {
       draw_pipeline_run( fpme->draw,
-                         fpme->prim,
+                         fpme->output_prim,
                          pipeline_verts,
                          count,
                          fpme->vertex_size,
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 5525dfc..fd33a54 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -103,7 +103,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
    unsigned clipped = 0;
    unsigned j;
 
-   if (0) debug_printf("%s\n", __FUNCTION__);
+   if (0) debug_printf("%s count, %d\n", __FUNCTION__, count);
 
    for (j = 0; j < count; j++) {
       float *position = out->data[pos];
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c
index d0e16c9..5ea8330 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray.c
+++ b/src/gallium/auxiliary/draw/draw_pt_varray.c
@@ -136,7 +136,8 @@ static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = {
 
 
 static void varray_prepare(struct draw_pt_front_end *frontend,
-                           unsigned prim,
+                           unsigned in_prim,
+                           unsigned out_prim,
                            struct draw_pt_middle_end *middle,
                            unsigned opt)
 {
@@ -144,11 +145,12 @@ static void varray_prepare(struct draw_pt_front_end *frontend,
 
    varray->base.run = varray_run;
 
-   varray->input_prim = prim;
-   varray->output_prim = decompose_prim[prim];
+   varray->input_prim = in_prim;
+   varray->output_prim = decompose_prim[out_prim];
 
    varray->middle = middle;
-   middle->prepare(middle, varray->output_prim, opt, &varray->driver_fetch_max );
+   middle->prepare(middle, varray->input_prim,
+                   varray->output_prim, opt, &varray->driver_fetch_max );
 
    /* check that the max is even */
    assert((varray->driver_fetch_max & 1) == 0);
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index 6a48e61..914c87a 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -54,7 +54,7 @@ struct vcache_frontend {
    unsigned draw_count;
    unsigned fetch_count;
    unsigned fetch_max;
-   
+
    struct draw_pt_middle_end *middle;
 
    unsigned input_prim;
@@ -64,14 +64,15 @@ struct vcache_frontend {
    unsigned opt;
 };
 
-static INLINE void 
+static INLINE void
 vcache_flush( struct vcache_frontend *vcache )
 {
    if (vcache->middle_prim != vcache->output_prim) {
       vcache->middle_prim = vcache->output_prim;
-      vcache->middle->prepare( vcache->middle, 
-                               vcache->middle_prim, 
-                               vcache->opt, 
+      vcache->middle->prepare( vcache->middle,
+                               vcache->input_prim,
+                               vcache->middle_prim,
+                               vcache->opt,
                                &vcache->fetch_max );
    }
 
@@ -356,19 +357,20 @@ vcache_check_run( struct draw_pt_front_end *frontend,
    if (0) debug_printf("fetch_count %d fetch_max %d draw_count %d\n", fetch_count, 
                        vcache->fetch_max,
                        draw_count);
-      
+
    if (elt_bias + max_index >= DRAW_PIPE_MAX_VERTICES ||
        fetch_count >= UNDEFINED_VERTEX_ID ||
        fetch_count > draw_count) {
       if (0) debug_printf("fail\n");
       goto fail;
    }
-      
+
    if (vcache->middle_prim != vcache->input_prim) {
       vcache->middle_prim = vcache->input_prim;
-      vcache->middle->prepare( vcache->middle, 
-                               vcache->middle_prim, 
-                               vcache->opt, 
+      vcache->middle->prepare( vcache->middle,
+                               vcache->input_prim,
+                               vcache->middle_prim,
+                               vcache->opt,
                                &vcache->fetch_max );
    }
 
@@ -467,9 +469,10 @@ vcache_check_run( struct draw_pt_front_end *frontend,
 
 
 
-static void 
+static void
 vcache_prepare( struct draw_pt_front_end *frontend,
-                unsigned prim,
+                unsigned in_prim,
+                unsigned out_prim,
                 struct draw_pt_middle_end *middle,
                 unsigned opt )
 {
@@ -479,13 +482,13 @@ vcache_prepare( struct draw_pt_front_end *frontend,
    {
       vcache->base.run = vcache_run_extras;
    }
-   else 
+   else
    {
       vcache->base.run = vcache_check_run;
    }
 
-   vcache->input_prim = prim;
-   vcache->output_prim = u_reduced_prim(prim);
+   vcache->input_prim = in_prim;
+   vcache->output_prim = u_reduced_prim(out_prim);
 
    vcache->middle = middle;
    vcache->opt = opt;
@@ -494,7 +497,8 @@ vcache_prepare( struct draw_pt_front_end *frontend,
     * doing so:
     */
    vcache->middle_prim = (opt & PT_PIPELINE) ? vcache->output_prim : vcache->input_prim;
-   middle->prepare( middle, vcache->middle_prim, opt, &vcache->fetch_max );
+   middle->prepare( middle, vcache->input_prim,
+                    vcache->middle_prim, opt, &vcache->fetch_max );
 }
 
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 5fda808..7d357e1 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -1236,7 +1236,7 @@ static void emit_decls( struct ureg_program *ureg )
       assert(ureg->processor == TGSI_PROCESSOR_GEOMETRY);
 
       emit_property(ureg,
-                    TGSI_PROPERTY_GS_MAX_VERTICES,
+                    TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES,
                     ureg->property_gs_max_vertices);
    }
 
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index 0a70237..c46c7e3 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -173,7 +173,7 @@ union tgsi_immediate_data
 
 #define TGSI_PROPERTY_GS_INPUT_PRIM          0
 #define TGSI_PROPERTY_GS_OUTPUT_PRIM         1
-#define TGSI_PROPERTY_GS_MAX_VERTICES        2
+#define TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES 2
 #define TGSI_PROPERTY_FS_COORD_ORIGIN        3
 #define TGSI_PROPERTY_FS_COORD_PIXEL_CENTER  4
 #define TGSI_PROPERTY_COUNT                  5
diff --git a/src/gallium/tests/graw/geometry-shader/line.txt b/src/gallium/tests/graw/geometry-shader/line.txt
index 93d5444..8be3f7f 100644
--- a/src/gallium/tests/graw/geometry-shader/line.txt
+++ b/src/gallium/tests/graw/geometry-shader/line.txt
@@ -1,6 +1,7 @@
 GEOM
 PROPERTY GS_INPUT_PRIMITIVE TRIANGLES
-PROPERTY GS_OUTPUT_PRIMITIVE LINES
+PROPERTY GS_OUTPUT_PRIMITIVE LINE_STRIP
+PROPERTY GS_MAX_OUTPUT_VERTICES 4
 DCL IN[][0], POSITION, CONSTANT
 DCL IN[][1], COLOR, CONSTANT
 DCL OUT[0], POSITION, CONSTANT



More information about the mesa-commit mailing list