Mesa (master): gallium: add interface for DrawAuto and implement it in softpipe

Zack Rusin zack at kemper.freedesktop.org
Tue Jun 8 03:32:00 PDT 2010


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

Author: Zack Rusin <zack at kde.org>
Date:   Mon May 31 20:41:18 2010 -0400

gallium: add interface for DrawAuto and implement it in softpipe

---

 src/gallium/drivers/softpipe/sp_context.c     |    1 +
 src/gallium/drivers/softpipe/sp_context.h     |    6 +++
 src/gallium/drivers/softpipe/sp_draw_arrays.c |   51 +++++++++++++++++++++++++
 src/gallium/drivers/softpipe/sp_state.h       |    2 +
 src/gallium/drivers/softpipe/sp_state_so.c    |   11 +++++-
 src/gallium/include/pipe/p_context.h          |    5 ++
 6 files changed, 75 insertions(+), 1 deletions(-)

diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index b197014..38bc0d5 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -276,6 +276,7 @@ softpipe_create_context( struct pipe_screen *screen,
    softpipe->pipe.draw_range_elements = softpipe_draw_range_elements;
    softpipe->pipe.draw_arrays_instanced = softpipe_draw_arrays_instanced;
    softpipe->pipe.draw_elements_instanced = softpipe_draw_elements_instanced;
+   softpipe->pipe.draw_auto = softpipe_draw_auto;
 
    softpipe->pipe.clear = softpipe_clear;
    softpipe->pipe.flush = softpipe_flush;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index f8ffc57..79165fb 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -80,6 +80,12 @@ struct softpipe_context {
    struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+   struct {
+      struct softpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
+      int offset[PIPE_MAX_SO_BUFFERS];
+      int so_count[PIPE_MAX_SO_BUFFERS];
+      int num_buffers;
+   } so_target;
 
    unsigned num_samplers;
    unsigned num_sampler_views;
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index b30036e..8fa7f9f 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -84,6 +84,57 @@ softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
                                           1);
 }
 
+void
+softpipe_draw_auto(struct pipe_context *pipe, unsigned mode)
+{
+   struct softpipe_context *sp = softpipe_context(pipe);
+   struct draw_context *draw = sp->draw;
+   const unsigned start = 0;
+   const unsigned count = sp->so_target.so_count[0];
+   void *buf = sp->so_target.buffer[0]->data;
+   int offset = sp->so_target.offset[0];
+
+   if (!softpipe_check_render_cond(sp) ||
+       sp->so_target.num_buffers != 1)
+      return;
+
+   sp->reduced_api_prim = u_reduced_prim(mode);
+
+   if (sp->dirty) {
+      softpipe_update_derived(sp);
+   }
+
+   softpipe_map_transfers(sp);
+
+   /* Map so buffers */
+   if (offset < 0) /* we were appending so start from beginning */
+      offset = 0;
+   buf = (void*)((int32_t*)buf + offset);
+   draw_set_mapped_vertex_buffer(draw, 0, buf);
+
+   draw_set_mapped_element_buffer_range(draw,
+                                        0, 0,
+                                        start,
+                                        start + count - 1,
+                                        NULL);
+
+   /* draw! */
+   draw_arrays_instanced(draw, mode, start, count, 0, 1);
+
+   /* unmap vertex/index buffers - will cause draw module to flush */
+   draw_set_mapped_vertex_buffer(draw, 0, NULL);
+
+   /*
+    * TODO: Flush only when a user vertex/index buffer is present
+    * (or even better, modify draw module to do this
+    * internally when this condition is seen?)
+    */
+   draw_flush(draw);
+
+   /* Note: leave drawing surfaces mapped */
+   sp->dirty_render_cache = TRUE;
+}
+
 
 void
 softpipe_draw_range_elements(struct pipe_context *pipe,
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index dd958eb..4ffa2b9 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -250,6 +250,8 @@ softpipe_draw_elements_instanced(struct pipe_context *pipe,
                                  unsigned startInstance,
                                  unsigned instanceCount);
 
+void softpipe_draw_auto(struct pipe_context *pipe, unsigned mode);
+
 void
 softpipe_map_transfers(struct softpipe_context *sp);
 
diff --git a/src/gallium/drivers/softpipe/sp_state_so.c b/src/gallium/drivers/softpipe/sp_state_so.c
index 49bde22..8bd20cd 100644
--- a/src/gallium/drivers/softpipe/sp_state_so.c
+++ b/src/gallium/drivers/softpipe/sp_state_so.c
@@ -93,7 +93,14 @@ softpipe_set_stream_output_buffers(struct pipe_context *pipe,
    softpipe->dirty |= SP_NEW_SO_BUFFERS;
 
    for (i = 0; i < num_buffers; ++i) {
-      void *mapped = softpipe_resource(buffers[i])->data;
+      void *mapped;
+      struct softpipe_resource *res = softpipe_resource(buffers[i]);
+
+      softpipe->so_target.buffer[i] = res;
+      softpipe->so_target.offset[i] = offsets[i];
+      softpipe->so_target.so_count[i] = 0;
+
+      mapped = res->data;
       if (offsets[i] >= 0)
          map_buffers[i] = ((char*)mapped) + offsets[i];
       else {
@@ -102,5 +109,7 @@ softpipe_set_stream_output_buffers(struct pipe_context *pipe,
          map_buffers[i] = mapped;
       }
    }
+   softpipe->so_target.num_buffers = num_buffers;
+
    draw_set_mapped_so_buffers(softpipe->draw, map_buffers, num_buffers);
 }
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 0267ed8..3a792b0 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -101,6 +101,11 @@ struct pipe_context {
                                 unsigned mode, 
                                 unsigned start, 
                                 unsigned count);
+
+   /**
+    * Draw the stream output buffer at index 0
+    */
+   void (*draw_auto)( struct pipe_context *pipe, unsigned mode );
    /*@}*/
 
    /**



More information about the mesa-commit mailing list