gallium: add interface for DrawAuto and implement it in softpipe
authorZack Rusin <zack@kde.org>
Tue, 1 Jun 2010 00:41:18 +0000 (20:41 -0400)
committerZack Rusin <zackr@vmware.com>
Tue, 8 Jun 2010 10:28:11 +0000 (06:28 -0400)
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_draw_arrays.c
src/gallium/drivers/softpipe/sp_state.h
src/gallium/drivers/softpipe/sp_state_so.c
src/gallium/include/pipe/p_context.h

index b1970140d5037e2b1c80b49305e2d9635959f567..38bc0d51f343644938914a51b1cb4c4df1c3996d 100644 (file)
@@ -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;
index f8ffc5787d365f2e949182bd6861605be01ff338..79165fba32c15b76ecc0f5079427a105c61e16cc 100644 (file)
@@ -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;
index b30036e2303d85816ac8c44040ce71b69b26806d..8fa7f9fbdec469a0dcd8ddea2288cb9515984fd6 100644 (file)
@@ -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,
index dd958ebb53ed14881301d4f140098e2aee344e7a..4ffa2b9f598ec1e7c96304922d140652a9d26be8 100644 (file)
@@ -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);
 
index 49bde22e979b5b2dd40dbee4049df5b5b45dba13..8bd20cd2acaf10e3dd2e3f9cec1714b3232718a6 100644 (file)
@@ -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);
 }
index 0267ed8fa4a8fd19f10af2aa3baa5371618a3f73..3a792b0fe0fc49cbe9fd09b72b4d50b5d15e887b 100644 (file)
@@ -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 );
    /*@}*/
 
    /**