implement linear emition and fetching and plug it in the varray paths
authorZack Rusin <zack@tungstengraphics.com>
Sun, 4 May 2008 02:32:17 +0000 (22:32 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Thu, 8 May 2008 19:26:08 +0000 (15:26 -0400)
src/gallium/auxiliary/draw/draw_pt.h
src/gallium/auxiliary/draw/draw_pt_emit.c
src/gallium/auxiliary/draw/draw_pt_fetch.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
src/gallium/auxiliary/draw/draw_pt_varray.c
src/gallium/auxiliary/draw/draw_pt_varray_tmp.h

index 2dec376..2f96cea 100644 (file)
@@ -92,6 +92,12 @@ struct draw_pt_middle_end {
                 const ushort *draw_elts,
                 unsigned draw_count );
 
+   void (*run_linear)(struct draw_pt_middle_end *,
+                      unsigned fetch_start,
+                      unsigned fetch_count,
+                      const ushort *draw_elts,
+                      unsigned draw_count);
+
    void (*finish)( struct draw_pt_middle_end * );
    void (*destroy)( struct draw_pt_middle_end * );
 };
@@ -152,6 +158,13 @@ void draw_pt_emit( struct pt_emit *emit,
                   const ushort *elts,
                   unsigned count );
 
+void draw_pt_emit_linear( struct pt_emit *emit,
+                          const float (*vertex_data)[4],
+                          unsigned vertex_count,
+                          unsigned stride,
+                          unsigned start,
+                          unsigned count );
+
 void draw_pt_emit_destroy( struct pt_emit *emit );
 
 struct pt_emit *draw_pt_emit_create( struct draw_context *draw );
@@ -170,6 +183,11 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
                        unsigned count,
                        char *verts );
 
+void draw_pt_fetch_run_linear( struct pt_fetch *fetch,
+                               unsigned start,
+                               unsigned count,
+                               char *verts );
+
 void draw_pt_fetch_destroy( struct pt_fetch *fetch );
 
 struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw );
index f9ac167..2a961b7 100644 (file)
@@ -179,6 +179,51 @@ void draw_pt_emit( struct pt_emit *emit,
 }
 
 
+void draw_pt_emit_linear(struct pt_emit *emit,
+                         const float (*vertex_data)[4],
+                         unsigned vertex_count,
+                         unsigned stride,
+                         unsigned start,
+                         unsigned count)
+{
+   struct draw_context *draw = emit->draw;
+   struct translate *translate = emit->translate;
+   struct vbuf_render *render = draw->render;
+   void *hw_verts;
+
+   debug_printf("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
+   /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 
+    */
+   draw_do_flush( draw, DRAW_FLUSH_BACKEND );
+
+   hw_verts = render->allocate_vertices(render,
+                                       (ushort)translate->key.output_stride,
+                                       (ushort)count);
+   if (!hw_verts) {
+      assert(0);
+      return;
+   }
+
+   translate->set_buffer(translate, 0,
+                        vertex_data, stride);
+
+   translate->set_buffer(translate, 1,
+                        &draw->rasterizer->point_size,
+                        0);
+
+   translate->run(translate,
+                  0,
+                  vertex_count,
+                  hw_verts);
+
+   render->draw_arrays(render, start, count);
+
+   render->release_vertices(render,
+                           hw_verts,
+                           translate->key.output_stride,
+                           vertex_count);
+}
+
 struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
 {
    struct pt_emit *emit = CALLOC_STRUCT(pt_emit);
index 1f765b7..d7cc180 100644 (file)
@@ -167,6 +167,42 @@ void draw_pt_fetch_run( struct pt_fetch *fetch,
 }
 
 
+void draw_pt_fetch_run_linear( struct pt_fetch *fetch,
+                               unsigned start,
+                               unsigned count,
+                               char *verts )
+{
+   struct draw_context *draw = fetch->draw;
+   struct translate *translate = fetch->translate;
+   unsigned i;
+
+   for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
+      translate->set_buffer(translate,
+                           i,
+                           ((char *)draw->pt.user.vbuffer[i] +
+                            draw->pt.vertex_buffer[i].buffer_offset),
+                           draw->pt.vertex_buffer[i].pitch );
+   }
+
+   translate->run( translate,
+                   start,
+                   count,
+                   verts );
+
+   /* Edgeflags are hard to fit into a translate program, populate
+    * them separately if required.  In the setup above they are
+    * defaulted to one, so only need this if there is reason to change
+    * that default:
+    */
+   if (fetch->need_edgeflags) {
+      for (i = 0; i < count; i++) {
+         struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
+         vh->edgeflag = draw_pt_get_edgeflag( draw, start + i );
+      }
+   }
+}
+
+
 struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw )
 {
    struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch);
index 4ec2049..b1e08a8 100644 (file)
@@ -162,7 +162,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
                          fpme->vertex_size,
                          draw_elts,
                          draw_count );
-   } 
+   }
    else {
       draw_pt_emit( fpme->emit,
                    (const float (*)[4])pipeline_verts->data,
@@ -177,6 +177,83 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
 }
 
 
+static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
+                                       unsigned fetch_start,
+                                       unsigned fetch_count,
+                                       const ushort *draw_elts,
+                                       unsigned draw_count )
+{
+   struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
+   struct draw_context *draw = fpme->draw;
+   struct draw_vertex_shader *shader = draw->vertex_shader;
+   unsigned opt = fpme->opt;
+   unsigned alloc_count = align_int( 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.
+       */
+      assert(0);
+      return;
+   }
+
+   /* Fetch into our vertex buffer
+    */
+   draw_pt_fetch_run_linear( fpme->fetch,
+                             fetch_start,
+                             fetch_count,
+                             (char *)pipeline_verts );
+
+   /* Run the shader, note that this overwrites the data[] parts of
+    * the pipeline verts.  If there is no shader, ie a bypass shader,
+    * then the inputs == outputs, and are already in the correct
+    * place.
+    */
+   if (opt & PT_SHADE)
+   {
+      shader->run_linear(shader, 
+                        (const float (*)[4])pipeline_verts->data,
+                        (      float (*)[4])pipeline_verts->data,
+                        (const float (*)[4])draw->pt.user.constants,
+                        fetch_count,
+                        fpme->vertex_size,
+                        fpme->vertex_size);
+   }
+
+   if (draw_pt_post_vs_run( fpme->post_vs,
+                           pipeline_verts,
+                           fetch_count,
+                           fpme->vertex_size ))
+   {
+      opt |= PT_PIPELINE;
+   }
+
+   /* Do we need to run the pipeline?
+    */
+   if (opt & PT_PIPELINE) {
+      draw_pipeline_run( fpme->draw,
+                         fpme->prim,
+                         pipeline_verts,
+                         fetch_count,
+                         fpme->vertex_size,
+                         draw_elts,
+                         draw_count );
+   }
+   else {
+      draw_pt_emit_linear( fpme->emit,
+                           (const float (*)[4])pipeline_verts->data,
+                           fetch_count,
+                           fpme->vertex_size,
+                           0, /*start*/
+                           draw_count );
+   }
+
+   FREE(pipeline_verts);
+}
+
+
 
 static void fetch_pipeline_finish( struct draw_pt_middle_end *middle )
 {
@@ -206,10 +283,11 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context *
    if (!fpme)
       goto fail;
 
-   fpme->base.prepare = fetch_pipeline_prepare;
-   fpme->base.run     = fetch_pipeline_run;
-   fpme->base.finish  = fetch_pipeline_finish;
-   fpme->base.destroy = fetch_pipeline_destroy;
+   fpme->base.prepare        = fetch_pipeline_prepare;
+   fpme->base.run            = fetch_pipeline_run;
+   fpme->base.run_linear     = fetch_pipeline_linear_run;
+   fpme->base.finish         = fetch_pipeline_finish;
+   fpme->base.destroy        = fetch_pipeline_destroy;
 
    fpme->draw = draw;
 
index c9843bd..916373a 100644 (file)
@@ -75,6 +75,28 @@ static void varray_flush(struct varray_frontend *varray)
    varray->draw_count = 0;
 }
 
+static void varray_flush_linear(struct varray_frontend *varray)
+{
+   if (varray->draw_count) {
+      debug_printf("FLUSH LINEAR fc = %d, dc = %d\n",
+                   varray->fetch_count,
+                   varray->draw_count);
+      debug_printf("\telt0 = %d, eltx = %d, draw0 = %d, drawx = %d\n",
+                   varray->fetch_elts[0],
+                   varray->fetch_elts[varray->fetch_count-1],
+                   varray->draw_elts[0],
+                   varray->draw_elts[varray->draw_count-1]);
+      varray->middle->run_linear(varray->middle,
+                                 varray->fetch_elts[0],
+                                 varray->fetch_count,
+                                 varray->draw_elts,
+                                 varray->draw_count);
+   }
+
+   varray->fetch_count = 0;
+   varray->draw_count = 0;
+}
+
 static INLINE void fetch_init(struct varray_frontend *varray,
                               unsigned count)
 {
@@ -265,8 +287,8 @@ static void varray_prepare(struct draw_pt_front_end *frontend,
    if (opt & PT_PIPELINE)
    {
       varray->base.run = varray_run_extras;
-   } 
-   else 
+   }
+   else
    {
       varray->base.run = varray_run;
    }
index 073c1aa..67baafa 100644 (file)
@@ -17,7 +17,7 @@ static void FUNC(struct draw_pt_front_end *frontend,
 
    split_prim_inplace(varray->input_prim, &first, &incr);
 
-#if 1
+#if 0
    debug_printf("%s (%d) %d/%d\n", __FUNCTION__,
                 varray->input_prim,
                 start, count);
@@ -88,7 +88,7 @@ static void FUNC(struct draw_pt_front_end *frontend,
                      i + 0, i + 1, i + 2);
          }
          fetch_init(varray, end);
-         varray_flush(varray);
+         varray_flush_linear(varray);
       }
       break;