gallium: Implement draw_vbo and set_index_buffer for all drivers.
authorChia-I Wu <olv@lunarg.com>
Thu, 15 Jul 2010 20:35:58 +0000 (04:35 +0800)
committerChia-I Wu <olv@lunarg.com>
Thu, 29 Jul 2010 05:45:30 +0000 (13:45 +0800)
Some drivers define a generic function that is called by all drawing
functions.  To implement draw_vbo for such drivers, either draw_vbo
calls the generic function or the prototype of the generic function is
changed to match draw_vbo.

Other drivers have no such generic function.  draw_vbo is implemented by
calling either draw_arrays and draw_elements.

For most drivers, set_index_buffer does not mark the state dirty for
tracking.  Instead, the index buffer state is emitted whenever draw_vbo
is called, just like the case with draw_elements.  It surely can be
improved.

48 files changed:
src/gallium/auxiliary/util/u_draw_quad.h
src/gallium/drivers/cell/ppu/cell_context.h
src/gallium/drivers/cell/ppu/cell_draw_arrays.c
src/gallium/drivers/cell/ppu/cell_state_vertex.c
src/gallium/drivers/failover/fo_context.c
src/gallium/drivers/failover/fo_context.h
src/gallium/drivers/failover/fo_state.c
src/gallium/drivers/failover/fo_state_emit.c
src/gallium/drivers/galahad/glhd_context.c
src/gallium/drivers/i915/i915_context.c
src/gallium/drivers/i915/i915_context.h
src/gallium/drivers/i915/i915_state.c
src/gallium/drivers/i965/brw_context.h
src/gallium/drivers/i965/brw_draw.c
src/gallium/drivers/i965/brw_draw_upload.c
src/gallium/drivers/i965/brw_pipe_vertex.c
src/gallium/drivers/identity/id_context.c
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/llvmpipe/lp_draw_arrays.c
src/gallium/drivers/llvmpipe/lp_state_vertex.c
src/gallium/drivers/nv50/nv50_context.c
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_vbo.c
src/gallium/drivers/nvfx/nvfx_context.c
src/gallium/drivers/nvfx/nvfx_context.h
src/gallium/drivers/nvfx/nvfx_state.c
src/gallium/drivers/nvfx/nvfx_vbo.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_render_stencilref.c
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r600/r600_context.c
src/gallium/drivers/r600/r600_context.h
src/gallium/drivers/r600/r600_draw.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/rbug/rbug_context.c
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_vertex.c
src/gallium/drivers/svga/svga_context.h
src/gallium/drivers/svga/svga_pipe_draw.c
src/gallium/drivers/svga/svga_pipe_vertex.c
src/gallium/drivers/trace/tr_context.c
src/gallium/drivers/trace/tr_dump_state.c
src/gallium/drivers/trace/tr_dump_state.h

index 42eb1844289b6b87d5b4eb3646136c2dcbaa0fae..1c9f7526112d8cd24d05d003ac7a5e92c08a2caa 100644 (file)
 #define U_DRAWQUAD_H
 
 
+#include "pipe/p_compiler.h"
+#include "pipe/p_context.h"
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct pipe_resource;
 
+
+static INLINE void
+util_draw_init_info(struct pipe_draw_info *info)
+{
+   memset(info, 0, sizeof(*info));
+   info->instance_count = 1;
+   info->max_index = 0xffffffff;
+}
+
+
+static INLINE void
+util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count)
+{
+   struct pipe_draw_info info;
+
+   util_draw_init_info(&info);
+   info.mode = mode;
+   info.start = start;
+   info.count = count;
+   info.min_index = start;
+   info.max_index = start + count - 1;
+
+   pipe->draw_vbo(pipe, &info);
+}
+
+
 extern void 
 util_draw_vertex_buffer(struct pipe_context *pipe,
                         struct pipe_resource *vbuf, uint offset,
index dc46e59a2d39b7e349446f3617cc9a22f59138b0..d1aee62ba1eb2b46271f638e9bbd14fe907c82de 100644 (file)
@@ -132,6 +132,7 @@ struct cell_context
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
    uint num_vertex_buffers;
+   struct pipe_index_buffer index_buffer;
 
    ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS];
    ubyte *zsbuf_map;
index 6a1e4d8a646a976bff9104ec54d53e6432e10115..e06226fbfe36f5180e5740d26b4c394a021e5371 100644 (file)
@@ -34,6 +34,7 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_context.h"
 #include "util/u_inlines.h"
+#include "util/u_draw_quad.h"
 
 #include "cell_context.h"
 #include "cell_draw_arrays.h"
  * XXX should the element buffer be specified/bound with a separate function?
  */
 static void
-cell_draw_range_elements(struct pipe_context *pipe,
-                         struct pipe_resource *indexBuffer,
-                         unsigned indexSize,
-                         int indexBias,
-                         unsigned min_index,
-                         unsigned max_index,
-                         unsigned mode, unsigned start, unsigned count)
+cell_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct cell_context *cell = cell_context(pipe);
    struct draw_context *draw = cell->draw;
+   void *mapped_indices = NULL;
    unsigned i;
 
    if (cell->dirty)
@@ -83,18 +79,20 @@ cell_draw_range_elements(struct pipe_context *pipe,
       draw_set_mapped_vertex_buffer(draw, i, buf);
    }
    /* Map index buffer, if present */
-   if (indexBuffer) {
-      void *mapped_indexes = cell_resource(indexBuffer)->data;
-      draw_set_mapped_element_buffer(draw, indexSize, indexBias, mapped_indexes);
-   }
-   else {
-      /* no index/element buffer */
-      draw_set_mapped_element_buffer(draw, 0, 0, NULL);
+   if (info->indexed && cell->index_buffer.buffer) {
+      mapped_indices = cell_resource(cell->index_buffer.buffer)->data;
+      mapped_indices += cell->index_buffer.offset;
    }
 
+   draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
+                                        lp->index_buffer.index_size : 0,
+                                        info->index_bias,
+                                        info->min_index,
+                                        info->max_index,
+                                        mapped_indices);
 
    /* draw! */
-   draw_arrays(draw, mode, start, count);
+   draw_arrays(draw, info->mode, info->start, info->count);
 
    /*
     * unmap vertex/index buffers - will cause draw module to flush
@@ -102,7 +100,7 @@ cell_draw_range_elements(struct pipe_context *pipe,
    for (i = 0; i < cell->num_vertex_buffers; i++) {
       draw_set_mapped_vertex_buffer(draw, i, NULL);
    }
-   if (indexBuffer) {
+   if (mapped_indices) {
       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
    }
 
@@ -115,6 +113,44 @@ cell_draw_range_elements(struct pipe_context *pipe,
 }
 
 
+static void
+cell_draw_range_elements(struct pipe_context *pipe,
+                         struct pipe_resource *indexBuffer,
+                         unsigned indexSize,
+                         int indexBias,
+                         unsigned min_index,
+                         unsigned max_index,
+                         unsigned mode, unsigned start, unsigned count)
+{
+   struct cell_context *cell = cell_context(pipe);
+   struct pipe_draw_info info;
+   struct pipe_index_buffer saved_ib, ib;
+
+   util_draw_init_info(&info);
+   info.mode = mode;
+   info.start = start;
+   info.count = count;
+   info.index_bias = indexBias;
+   info.min_index = min_index;
+   info.max_index = max_index;
+
+   if (indexBuffer) {
+      info.indexed = TRUE;
+      saved_ib = cell->index_buffer;
+
+      ib.buffer = indexBuffer;
+      ib.offset = 0;
+      ib.index_size = indexSize;
+      pipe->set_index_buffer(pipe, &ib);
+   }
+
+   cell_draw_vbo(pipe, &info);
+
+   if (indexBuffer)
+      pipe->set_index_buffer(pipe, &saved_ib);
+}
+
+
 static void
 cell_draw_elements(struct pipe_context *pipe,
                    struct pipe_resource *indexBuffer,
@@ -142,5 +178,6 @@ cell_init_draw_functions(struct cell_context *cell)
    cell->pipe.draw_arrays = cell_draw_arrays;
    cell->pipe.draw_elements = cell_draw_elements;
    cell->pipe.draw_range_elements = cell_draw_range_elements;
+   cell->pipe.draw_vbo = cell_draw_vbo;
 }
 
index 69152b6cbf36bb233e19784896b7a9f2c8e63aed..4e3701cd0acb85ce75f154b1b3abc453da4379aa 100644 (file)
@@ -91,10 +91,26 @@ cell_set_vertex_buffers(struct pipe_context *pipe,
 }
 
 
+static void
+cell_set_index_buffer(struct pipe_context *pipe,
+                      const struct pipe_index_buffer *ib)
+{
+   struct cell_context *cell = cell_context(pipe);
+
+   if (ib)
+      memcpy(&cell->index_buffer, ib, sizeof(cell->index_buffer));
+   else
+      memset(&cell->index_buffer, 0, sizeof(cell->index_buffer));
+
+   /* TODO make this more like a state */
+}
+
+
 void
 cell_init_vertex_functions(struct cell_context *cell)
 {
    cell->pipe.set_vertex_buffers = cell_set_vertex_buffers;
+   cell->pipe.set_index_buffer = cell_set_index_buffer;
    cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state;
    cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state;
    cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state;
index 9c9c1bdc4522e9c6e036b1c4c75178a599f2d0ed..1048d58313d19846a19567e65cd1a299a7146447 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "pipe/p_defines.h"
 #include "util/u_memory.h"
+#include "util/u_draw_quad.h"
 #include "pipe/p_context.h"
 
 #include "fo_context.h"
@@ -50,13 +51,8 @@ void failover_fail_over( struct failover_context *failover )
 }
 
 
-static void failover_draw_elements( struct pipe_context *pipe,
-                                    struct pipe_resource *indexResource,
-                                    unsigned indexSize,
-                                    int indexBias,
-                                    unsigned prim, 
-                                    unsigned start, 
-                                    unsigned count)
+static void failover_draw_vbo( struct pipe_context *pipe,
+                               const struct pipe_draw_info *info)
 {
    struct failover_context *failover = failover_context( pipe );
 
@@ -70,13 +66,7 @@ static void failover_draw_elements( struct pipe_context *pipe,
    /* Try hardware:
     */
    if (failover->mode == FO_HW) {
-      failover->hw->draw_elements( failover->hw, 
-                                   indexResource, 
-                                   indexSize, 
-                                   indexBias,
-                                   prim, 
-                                   start, 
-                                   count );
+      failover->hw->draw_vbo( failover->hw, info );
    }
 
    /* Possibly try software:
@@ -88,13 +78,7 @@ static void failover_draw_elements( struct pipe_context *pipe,
         failover_state_emit( failover );
       }
 
-      failover->sw->draw_elements( failover->sw, 
-                                  indexResource, 
-                                  indexSize, 
-                                  indexBias,
-                                  prim, 
-                                  start, 
-                                  count );
+      failover->sw->draw_vbo( failover->sw, info );
 
       /* Be ready to switch back to hardware rendering without an
        * intervening flush.  Unlikely to be much performance impact to
@@ -105,6 +89,40 @@ static void failover_draw_elements( struct pipe_context *pipe,
 }
 
 
+static void failover_draw_elements( struct pipe_context *pipe,
+                                    struct pipe_resource *indexResource,
+                                    unsigned indexSize,
+                                    int indexBias,
+                                    unsigned prim, 
+                                    unsigned start, 
+                                    unsigned count)
+{
+   struct failover_context *failover = failover_context( pipe );
+   struct pipe_draw_info info;
+   struct pipe_index_buffer saved_ib, ib;
+
+   util_draw_init_info(&info);
+   info.mode = prim;
+   info.start = start;
+   info.count = count;
+
+   if (indexResource) {
+      info.indexed = TRUE;
+      saved_ib = failover->index_buffer;
+
+      ib.buffer = indexResource;
+      ib.offset = 0;
+      ib.index_size = indexSize;
+      pipe->set_index_buffer(pipe, &ib);
+   }
+
+   failover_draw_vbo(pipe, &info);
+
+   if (indexResource)
+      pipe->set_index_buffer(pipe, &saved_ib);
+}
+
+
 static void failover_draw_arrays( struct pipe_context *pipe,
                                     unsigned prim, unsigned start, unsigned count)
 {
@@ -145,6 +163,7 @@ struct pipe_context *failover_create( struct pipe_context *hw,
 
    failover->pipe.draw_arrays = failover_draw_arrays;
    failover->pipe.draw_elements = failover_draw_elements;
+   failover->pipe.draw_vbo = failover_draw_vbo;
    failover->pipe.clear = hw->clear;
    failover->pipe.clear_render_target = hw->clear_render_target;
    failover->pipe.clear_depth_stencil = hw->clear_depth_stencil;
index 9d3e0d0dba0d24c7509e2ed5376dd1fb1ca2a9fb..1afa6c9ceede6cefd3ff9ff5dc316c31bf1d2f44 100644 (file)
@@ -56,6 +56,7 @@
 #define FO_NEW_VERTEX_BUFFER   0x40000
 #define FO_NEW_VERTEX_ELEMENT  0x80000
 #define FO_NEW_SAMPLE_MASK     0x100000
+#define FO_NEW_INDEX_BUFFER    0x200000
 
 
 
@@ -97,6 +98,7 @@ struct failover_context {
    struct pipe_scissor_state scissor;
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
+   struct pipe_index_buffer index_buffer;
 
    uint num_vertex_buffers;
 
index 12e42379f98b95c345657bbd54da6e4c77f85c98..c265f381b6755559f668eb8e1ac6353d6e843744 100644 (file)
@@ -583,6 +583,23 @@ failover_set_vertex_buffers(struct pipe_context *pipe,
 }
 
 
+static void
+failover_set_index_buffer(struct pipe_context *pipe,
+                          const struct pipe_index_buffer *ib)
+{
+   struct failover_context *failover = failover_context(pipe);
+
+   if (ib)
+      memcpy(&failover->index_buffer, ib, sizeof(failover->index_buffer));
+   else
+      memset(&failover->index_buffer, 0, sizeof(failover->index_buffer));
+
+   failover->dirty |= FO_NEW_INDEX_BUFFER;
+   failover->sw->set_index_buffer( failover->sw, ib );
+   failover->hw->set_index_buffer( failover->hw, ib );
+}
+
+
 void
 failover_set_constant_buffer(struct pipe_context *pipe,
                              uint shader, uint index,
@@ -635,6 +652,7 @@ failover_init_state_functions( struct failover_context *failover )
    failover->pipe.set_vertex_sampler_views = failover_set_vertex_sampler_views;
    failover->pipe.set_viewport_state = failover_set_viewport_state;
    failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;
+   failover->pipe.set_index_buffer = failover_set_index_buffer;
    failover->pipe.set_constant_buffer = failover_set_constant_buffer;
    failover->pipe.create_sampler_view = failover_create_sampler_view;
    failover->pipe.sampler_view_destroy = failover_sampler_view_destroy;
index 147f23269ca252698eda843ad7a3eea373d309fe..7f434ff9d683872328bd268e23cacada15656cf6 100644 (file)
@@ -135,5 +135,10 @@ failover_state_emit( struct failover_context *failover )
                                         failover->vertex_buffers );
    }
 
+   if (failover->dirty & FO_NEW_INDEX_BUFFER) {
+      failover->sw->set_index_buffer( failover->sw,
+                                      &failover->index_buffer );
+   }
+
    failover->dirty = 0;
 }
index ab6f17b3ab8fbae6ea59dba8e65a32ac3bafa979..6473f2d499b27c5b2f8a10cc316ca4c0d92c2a8e 100644 (file)
@@ -112,6 +112,16 @@ galahad_draw_range_elements(struct pipe_context *_pipe,
                              count);
 }
 
+static void
+galahad_draw_vbo(struct pipe_context *_pipe,
+                 const struct pipe_draw_info *info)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->draw_vbo(pipe, info);
+}
+
 static struct pipe_query *
 galahad_create_query(struct pipe_context *_pipe,
                       unsigned query_type)
@@ -650,6 +660,41 @@ galahad_set_vertex_buffers(struct pipe_context *_pipe,
                             num_buffers,
                             buffers);
 }
+
+static void
+galahad_set_index_buffer(struct pipe_context *_pipe,
+                         const struct pipe_index_buffer *_ib)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_index_buffer unwrapped_ib, *ib = NULL;
+
+   if (_ib->buffer) {
+      switch (_ib->index_size) {
+      case 1:
+      case 2:
+      case 4:
+         break;
+      default:
+         glhd_warn("index buffer %p has unrecognized index size %d",
+               _ib->buffer, _ib->index_size);
+         break;
+      }
+   }
+   else if (_ib->offset || _ib->index_size) {
+      glhd_warn("non-indexed state with index offset %d and index size %d",
+            _ib->offset, _ib->index_size);
+   }
+
+   if (_ib) {
+      unwrapped_ib = *_ib;
+      unwrapped_ib.buffer = galahad_resource_unwrap(_ib->buffer);
+      ib = &unwrapped_ib;
+   }
+
+   pipe->set_index_buffer(pipe, ib);
+}
+
 static void
 galahad_resource_copy_region(struct pipe_context *_pipe,
                               struct pipe_resource *_dst,
@@ -937,6 +982,7 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    glhd_pipe->base.draw_arrays = galahad_draw_arrays;
    glhd_pipe->base.draw_elements = galahad_draw_elements;
    glhd_pipe->base.draw_range_elements = galahad_draw_range_elements;
+   glhd_pipe->base.draw_vbo = galahad_draw_vbo;
    glhd_pipe->base.create_query = galahad_create_query;
    glhd_pipe->base.destroy_query = galahad_destroy_query;
    glhd_pipe->base.begin_query = galahad_begin_query;
@@ -976,6 +1022,7 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    glhd_pipe->base.set_fragment_sampler_views = galahad_set_fragment_sampler_views;
    glhd_pipe->base.set_vertex_sampler_views = galahad_set_vertex_sampler_views;
    glhd_pipe->base.set_vertex_buffers = galahad_set_vertex_buffers;
+   glhd_pipe->base.set_index_buffer = galahad_set_index_buffer;
    glhd_pipe->base.resource_copy_region = galahad_resource_copy_region;
    glhd_pipe->base.clear = galahad_clear;
    glhd_pipe->base.clear_render_target = galahad_clear_render_target;
index 2af9bdac956daf44b078d63a34c82ab8143bfea6..ca07b3e235179ddd630e1ae01feceff4a573c106 100644 (file)
@@ -36,6 +36,7 @@
 #include "pipe/p_defines.h"
 #include "util/u_inlines.h"
 #include "util/u_memory.h"
+#include "util/u_draw_quad.h"
 #include "pipe/p_screen.h"
 
 
 
 
 static void
-i915_draw_range_elements(struct pipe_context *pipe,
-                         struct pipe_resource *indexBuffer,
-                         unsigned indexSize,
-                         int indexBias,
-                         unsigned min_index,
-                         unsigned max_index,
-                         unsigned prim, unsigned start, unsigned count)
+i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct i915_context *i915 = i915_context(pipe);
    struct draw_context *draw = i915->draw;
+   void *mapped_indices = NULL;
    unsigned i;
 
    if (i915->dirty)
@@ -71,16 +67,18 @@ i915_draw_range_elements(struct pipe_context *pipe,
    /*
     * Map index buffer, if present
     */
-   if (indexBuffer) {
-      void *mapped_indexes = i915_buffer(indexBuffer)->data;
-      draw_set_mapped_element_buffer_range(draw, indexSize, indexBias,
-                                           min_index,
-                                           max_index,
-                                           mapped_indexes);
-   } else {
-      draw_set_mapped_element_buffer(draw, 0, 0, NULL);
+   if (info->indexed && i915->index_buffer.buffer) {
+      mapped_indices = i915_buffer(i915->index_buffer.buffer)->data;
+      mapped_indices += i915->index_buffer.offset;
    }
 
+   draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
+                                        i915->index_buffer.index_size : 0,
+                                        info->index_bias,
+                                        info->min_index,
+                                        info->max_index,
+                                        mapped_indices);
+
 
    draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
                                    i915->current.constants[PIPE_SHADER_VERTEX],
@@ -90,7 +88,7 @@ i915_draw_range_elements(struct pipe_context *pipe,
    /*
     * Do the drawing
     */
-   draw_arrays(i915->draw, prim, start, count);
+   draw_arrays(i915->draw, info->mode, info->start, info->count);
 
    /*
     * unmap vertex/index buffers
@@ -99,11 +97,48 @@ i915_draw_range_elements(struct pipe_context *pipe,
       draw_set_mapped_vertex_buffer(draw, i, NULL);
    }
 
-   if (indexBuffer) {
+   if (mapped_indices) {
       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
    }
 }
 
+static void
+i915_draw_range_elements(struct pipe_context *pipe,
+                         struct pipe_resource *indexBuffer,
+                         unsigned indexSize,
+                         int indexBias,
+                         unsigned min_index,
+                         unsigned max_index,
+                         unsigned prim, unsigned start, unsigned count)
+{
+   struct i915_context *i915 = i915_context(pipe);
+   struct pipe_draw_info info;
+   struct pipe_index_buffer saved_ib, ib;
+
+   util_draw_init_info(&info);
+   info.mode = prim;
+   info.start = start;
+   info.count = count;
+   info.index_bias = indexBias;
+   info.min_index = min_index;
+   info.max_index = max_index;
+
+   if (indexBuffer) {
+      info.indexed = TRUE;
+      saved_ib = i915->index_buffer;
+
+      ib.buffer = indexBuffer;
+      ib.offset = 0;
+      ib.index_size = indexSize;
+      pipe->set_index_buffer(pipe, &ib);
+   }
+
+   i915_draw_vbo(pipe, &info);
+
+   if (indexBuffer)
+      pipe->set_index_buffer(pipe, &saved_ib);
+}
+
 static void
 i915_draw_elements(struct pipe_context *pipe,
                    struct pipe_resource *indexBuffer,
@@ -171,6 +206,7 @@ i915_create_context(struct pipe_screen *screen, void *priv)
    i915->base.draw_arrays = i915_draw_arrays;
    i915->base.draw_elements = i915_draw_elements;
    i915->base.draw_range_elements = i915_draw_range_elements;
+   i915->base.draw_vbo = i915_draw_vbo;
 
    /*
     * Create drawing context and plug our rendering stage into it.
index b210cb130d09088283e3a2733b1206216d509ef6..3ae61d0ea70c0a0cfd4a5347e80ef775ba844ac7 100644 (file)
@@ -221,6 +221,7 @@ struct i915_context
    struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+   struct pipe_index_buffer index_buffer;
 
    unsigned dirty;
 
index e767aa9f8f09f174198bdb3bfe09afff452fb572..385c3b2d2d3ff91c5fb99427f0c707a1a3411e70 100644 (file)
@@ -812,6 +812,19 @@ i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
    FREE( velems );
 }
 
+static void i915_set_index_buffer(struct pipe_context *pipe,
+                                  const struct pipe_index_buffer *ib)
+{
+   struct i915_context *i915 = i915_context(pipe);
+
+   if (ib)
+      memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer));
+   else
+      memset(&i915->index_buffer, 0, sizeof(i915->index_buffer));
+
+   /* TODO make this more like a state */
+}
+
 static void
 i915_set_sample_mask(struct pipe_context *pipe,
                      unsigned sample_mask)
@@ -860,4 +873,5 @@ i915_init_state_functions( struct i915_context *i915 )
    i915->base.sampler_view_destroy = i915_sampler_view_destroy;
    i915->base.set_viewport_state = i915_set_viewport_state;
    i915->base.set_vertex_buffers = i915_set_vertex_buffers;
+   i915->base.set_index_buffer = i915_set_index_buffer;
 }
index 94c9c443f058c56ba72126a55c6de3c1922ed445..56d351f97d1f867b54b3435c631a1fe5348fcaf4 100644 (file)
@@ -576,6 +576,7 @@ struct brw_context
        */
       struct pipe_resource *index_buffer;
       unsigned index_size;
+      unsigned index_offset;
 
       /* Updates are signalled by PIPE_NEW_INDEX_RANGE:
        */
index 4625c2048f91e5744fe40448fa7c7848e38a11f8..fa7d047e0bd20af21e8fe1423deeb6c10cd1f1c7 100644 (file)
@@ -29,6 +29,7 @@
 #include "util/u_inlines.h"
 #include "util/u_prim.h"
 #include "util/u_upload_mgr.h"
+#include "util/u_draw_quad.h"
 
 #include "brw_draw.h"
 #include "brw_defines.h"
@@ -142,7 +143,7 @@ static int brw_emit_prim(struct brw_context *brw,
  */
 static int
 try_draw_range_elements(struct brw_context *brw,
-                       struct pipe_resource *index_buffer,
+                       boolean indexed,
                        unsigned hw_prim, 
                        unsigned start, unsigned count)
 {
@@ -165,7 +166,7 @@ try_draw_range_elements(struct brw_context *brw,
    if (ret)
       return ret;
    
-   ret = brw_emit_prim(brw, start, count, index_buffer != NULL, hw_prim);
+   ret = brw_emit_prim(brw, start, count, indexed, hw_prim);
    if (ret)
       return ret;
 
@@ -177,61 +178,86 @@ try_draw_range_elements(struct brw_context *brw,
 
 
 static void
-brw_draw_range_elements(struct pipe_context *pipe,
-                       struct pipe_resource *index_buffer,
-                       unsigned index_size, int index_bias,
-                       unsigned min_index,
-                       unsigned max_index,
-                       unsigned mode, unsigned start, unsigned count)
+brw_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct brw_context *brw = brw_context(pipe);
    int ret;
    uint32_t hw_prim;
 
-   hw_prim = brw_set_prim(brw, mode);
+   hw_prim = brw_set_prim(brw, info->mode);
 
    if (BRW_DEBUG & DEBUG_PRIMS)
       debug_printf("PRIM: %s start %d count %d index_buffer %p\n",
-                   u_prim_name(mode), start, count, (void *)index_buffer);
-
-   assert(index_bias == 0);
+                   u_prim_name(info->mode), info->start, info->count,
+                   (void *) brw->curr.index_buffer);
 
-   /* Potentially trigger upload of new index buffer.
-    *
-    * XXX: do we need to go through state validation to achieve this?
-    * Could just call upload code directly.
-    */
-   if (brw->curr.index_buffer != index_buffer ||
-       brw->curr.index_size != index_size) {
-      pipe_resource_reference( &brw->curr.index_buffer, index_buffer );
-      brw->curr.index_size = index_size;
-      brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER;
-   }
+   assert(info->index_bias == 0);
 
-   /* XXX: do we really care?
+   /* Potentially trigger upload of new index buffer range.
+    * XXX: do we really care?
     */
-   if (brw->curr.min_index != min_index ||
-       brw->curr.max_index != max_index) 
+   if (brw->curr.min_index != info->min_index ||
+       brw->curr.max_index != info->max_index) 
    { 
-      brw->curr.min_index = min_index;
-      brw->curr.max_index = max_index;
+      brw->curr.min_index = info->min_index;
+      brw->curr.max_index = info->max_index;
       brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE;
    }
 
 
    /* Make a first attempt at drawing:
     */
-   ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
+   ret = try_draw_range_elements(brw, info->indexed,
+         hw_prim, info->start, info->count);
 
    /* Otherwise, flush and retry:
     */
    if (ret != 0) {
       brw_context_flush( brw );
-      ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count );
+      ret = try_draw_range_elements(brw, info->indexed,
+            hw_prim, info->start, info->count);
       assert(ret == 0);
    }
 }
 
+static void
+brw_draw_range_elements(struct pipe_context *pipe,
+                       struct pipe_resource *index_buffer,
+                       unsigned index_size, int index_bias,
+                       unsigned min_index,
+                       unsigned max_index,
+                       unsigned mode, unsigned start, unsigned count)
+{
+   struct brw_context *brw = brw_context(pipe);
+   struct pipe_draw_info info;
+   struct pipe_index_buffer saved_ib, ib;
+
+   util_draw_init_info(&info);
+   info.mode = mode;
+   info.start = start;
+   info.count = count;
+   info.index_bias = index_bias;
+   info.min_index = min_index;
+   info.max_index = max_index;
+
+   if (index_buffer) {
+      info.indexed = TRUE;
+      saved_ib.buffer = brw->curr.index_buffer;
+      saved_ib.offset = brw->curr.index_offset;
+      saved_ib.index_size = brw->curr.index_size;
+
+      ib.buffer = index_buffer;
+      ib.offset = 0;
+      ib.index_size = index_size;
+      pipe->set_index_buffer(pipe, &ib);
+   }
+
+   brw_draw_vbo(pipe, &info);
+
+   if (index_buffer)
+      pipe->set_index_buffer(pipe, &saved_ib);
+}
+
 static void
 brw_draw_elements(struct pipe_context *pipe,
                  struct pipe_resource *index_buffer,
@@ -262,6 +288,7 @@ boolean brw_draw_init( struct brw_context *brw )
    brw->base.draw_arrays = brw_draw_arrays;
    brw->base.draw_elements = brw_draw_elements;
    brw->base.draw_range_elements = brw_draw_range_elements;
+   brw->base.draw_vbo = brw_draw_vbo;
 
    /* Create helpers for uploading data in user buffers:
     */
index 337eee8cd9ca185153389d200423abea68fd1c74..ebeb1e146aa9bee5d95f955131efa88b68daf3d1 100644 (file)
@@ -231,7 +231,7 @@ static int brw_prepare_indices(struct brw_context *brw)
    struct pipe_resource *upload_buf = NULL;
    struct brw_winsys_buffer *bo = NULL;
    GLuint offset;
-   GLuint index_size;
+   GLuint index_size, index_offset;
    GLuint ib_size;
    int ret;
 
@@ -246,13 +246,14 @@ static int brw_prepare_indices(struct brw_context *brw)
 
    ib_size = index_buffer->width0;
    index_size = brw->curr.index_size;
+   index_offset = brw->curr.index_offset;
 
    /* Turn userbuffer into a proper hardware buffer?
     */
    if (brw_buffer_is_user_buffer(index_buffer)) {
 
       ret = u_upload_buffer( brw->vb.upload_index,
-                            0,
+                            index_offset,
                             ib_size,
                             index_buffer,
                             &offset,
@@ -269,7 +270,7 @@ static int brw_prepare_indices(struct brw_context *brw)
    else {
       bo = brw_buffer(index_buffer)->bo;
       ib_size = bo->size;
-      offset = 0;
+      offset = index_offset;
    }
 
    /* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading the
index 4a120a51dad479de8fd94964136a2dca97880742..007239efc40424756f2df4dbc4452a80bbf7e9b0 100644 (file)
@@ -274,10 +274,41 @@ static void brw_set_vertex_buffers(struct pipe_context *pipe,
 }
 
 
+static void brw_set_index_buffer(struct pipe_context *pipe,
+                                 const struct pipe_index_buffer *ib)
+{
+   struct brw_context *brw = brw_context(pipe);
+
+   if (ib) {
+      if (brw->curr.index_buffer == ib->buffer &&
+          brw->curr.index_offset == ib->offset &&
+          brw->curr.index_size == ib->index_size)
+         return;
+
+      pipe_resource_reference(&brw->curr.index_buffer, ib->buffer);
+      brw->curr.index_offset = ib->offset;
+      brw->curr.index_size = ib->index_size;
+   }
+   else {
+      if (!brw->curr.index_buffer &&
+          !brw->curr.index_offset &&
+          !brw->curr.index_size)
+         return;
+
+      pipe_resource_reference(&brw->curr.index_buffer, NULL);
+      brw->curr.index_offset = 0;
+      brw->curr.index_size = 0;
+   }
+
+   brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER;
+}
+
+
 void 
 brw_pipe_vertex_init( struct brw_context *brw )
 {
    brw->base.set_vertex_buffers = brw_set_vertex_buffers;
+   brw->base.set_index_buffer = brw_set_index_buffer;
    brw->base.create_vertex_elements_state = brw_create_vertex_elements_state;
    brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state;
    brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state;
index 67be895b38592bf1a9a813d5824b287289d004e1..e10d3a141306392f91152c5fffa105944dae77b4 100644 (file)
@@ -110,6 +110,16 @@ identity_draw_range_elements(struct pipe_context *_pipe,
                              count);
 }
 
+static void
+identity_draw_vbo(struct pipe_context *_pipe,
+                  const struct pipe_draw_info *info)
+{
+   struct identity_context *id_pipe = identity_context(_pipe);
+   struct pipe_context *pipe = id_pipe->pipe;
+
+   pipe->draw_vbo(pipe, info);
+}
+
 static struct pipe_query *
 identity_create_query(struct pipe_context *_pipe,
                       unsigned query_type)
@@ -611,6 +621,24 @@ identity_set_vertex_buffers(struct pipe_context *_pipe,
                             num_buffers,
                             buffers);
 }
+
+static void
+identity_set_index_buffer(struct pipe_context *_pipe,
+                          const struct pipe_index_buffer *_ib)
+{
+   struct identity_context *id_pipe = identity_context(_pipe);
+   struct pipe_context *pipe = id_pipe->pipe;
+   struct pipe_index_buffer unwrapped_ib, *ib = NULL;
+
+   if (_ib) {
+      unwrapped_ib = *_ib;
+      unwrapped_ib.buffer = identity_resource_unwrap(_ib->buffer);
+      ib = &unwrapped_ib;
+   }
+
+   pipe->set_index_buffer(pipe, ib);
+}
+
 static void
 identity_resource_copy_region(struct pipe_context *_pipe,
                               struct pipe_resource *_dst,
@@ -892,6 +920,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    id_pipe->base.draw_arrays = identity_draw_arrays;
    id_pipe->base.draw_elements = identity_draw_elements;
    id_pipe->base.draw_range_elements = identity_draw_range_elements;
+   id_pipe->base.draw_vbo = identity_draw_vbo;
    id_pipe->base.create_query = identity_create_query;
    id_pipe->base.destroy_query = identity_destroy_query;
    id_pipe->base.begin_query = identity_begin_query;
@@ -931,6 +960,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views;
    id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views;
    id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
+   id_pipe->base.set_index_buffer = identity_set_index_buffer;
    id_pipe->base.resource_copy_region = identity_resource_copy_region;
    id_pipe->base.clear = identity_clear;
    id_pipe->base.clear_render_target = identity_clear_render_target;
index b2643ab33cd27f934221c79b370ff3ec858b2ba9..50f9091c3ca743e0a27b9e3399b1f2756588f265 100644 (file)
@@ -77,6 +77,7 @@ struct llvmpipe_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 pipe_index_buffer index_buffer;
    struct {
       struct llvmpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
       int offset[PIPE_MAX_SO_BUFFERS];
index 625d0c8a8c95d464ba8f98eaa4233416ef871589..b6dbb9d288ebc5d565a28ec855280a87a8fd2ff2 100644 (file)
@@ -34,6 +34,7 @@
 #include "pipe/p_defines.h"
 #include "pipe/p_context.h"
 #include "util/u_prim.h"
+#include "util/u_draw_quad.h"
 
 #include "lp_context.h"
 #include "lp_state.h"
  * the drawing to the 'draw' module.
  */
 static void
-llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
-                                       struct pipe_resource *indexBuffer,
-                                       unsigned indexSize,
-                                       int indexBias,
-                                       unsigned minIndex,
-                                       unsigned maxIndex,
-                                       unsigned mode,
-                                       unsigned start,
-                                       unsigned count,
-                                       unsigned startInstance,
-                                       unsigned instanceCount)
+llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct llvmpipe_context *lp = llvmpipe_context(pipe);
    struct draw_context *draw = lp->draw;
+   void *mapped_indices = NULL;
    unsigned i;
 
    if (lp->dirty)
@@ -77,27 +69,25 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
    }
 
    /* Map index buffer, if present */
-   if (indexBuffer) {
-      void *mapped_indexes = llvmpipe_resource_data(indexBuffer);
-      draw_set_mapped_element_buffer_range(draw,
-                                           indexSize,
-                                           indexBias,
-                                           minIndex,
-                                           maxIndex,
-                                           mapped_indexes);
-   }
-   else {
-      /* no index/element buffer */
-      draw_set_mapped_element_buffer_range(draw, 0, 0, start,
-                                           start + count - 1, NULL);
+   if (info->indexed && lp->index_buffer.buffer) {
+      mapped_indices = llvmpipe_resource_data(lp->index_buffer.buffer);
+      mapped_indices += lp->index_buffer.offset;
    }
+
+   draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
+                                        lp->index_buffer.index_size : 0,
+                                        info->index_bias,
+                                        info->min_index,
+                                        info->max_index,
+                                        mapped_indices);
+
    llvmpipe_prepare_vertex_sampling(lp,
                                     lp->num_vertex_sampler_views,
                                     lp->vertex_sampler_views);
 
    /* draw! */
-   draw_arrays_instanced(draw, mode, start, count,
-                         startInstance, instanceCount);
+   draw_arrays_instanced(draw, info->mode, info->start, info->count,
+         info->start_instance, info->instance_count);
 
    /*
     * unmap vertex/index buffers
@@ -105,7 +95,7 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
    for (i = 0; i < lp->num_vertex_buffers; i++) {
       draw_set_mapped_vertex_buffer(draw, i, NULL);
    }
-   if (indexBuffer) {
+   if (mapped_indices) {
       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
    }
    llvmpipe_cleanup_vertex_sampling(lp);
@@ -119,6 +109,50 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
 }
 
 
+static void
+llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
+                                       struct pipe_resource *indexBuffer,
+                                       unsigned indexSize,
+                                       int indexBias,
+                                       unsigned minIndex,
+                                       unsigned maxIndex,
+                                       unsigned mode,
+                                       unsigned start,
+                                       unsigned count,
+                                       unsigned startInstance,
+                                       unsigned instanceCount)
+{
+   struct llvmpipe_context *lp = llvmpipe_context(pipe);
+   struct pipe_draw_info info;
+   struct pipe_index_buffer saved_ib, ib;
+
+   util_draw_init_info(&info);
+   info.mode = mode;
+   info.start = start;
+   info.count = count;
+   info.start_instance = startInstance;
+   info.instance_count = instanceCount;
+
+   info.index_bias = indexBias;
+   info.min_index = minIndex;
+   info.max_index = maxIndex;
+
+   if (indexBuffer) {
+      info.indexed = TRUE;
+      saved_ib = lp->index_buffer;
+
+      ib.buffer = indexBuffer;
+      ib.offset = 0;
+      ib.index_size = indexSize;
+      pipe->set_index_buffer(pipe, &ib);
+   }
+
+   llvmpipe_draw_vbo(pipe, &info);
+
+   if (indexBuffer)
+      pipe->set_index_buffer(pipe, &saved_ib);
+}
+
 static void
 llvmpipe_draw_arrays_instanced(struct pipe_context *pipe,
                                unsigned mode,
@@ -227,4 +261,6 @@ llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe)
    llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
    llvmpipe->pipe.draw_arrays_instanced = llvmpipe_draw_arrays_instanced;
    llvmpipe->pipe.draw_elements_instanced = llvmpipe_draw_elements_instanced;
+
+   llvmpipe->pipe.draw_vbo = llvmpipe_draw_vbo;
 }
index 113f13db0189c4935b62a2a1ad67f18798631d67..d86e66b4fb87c579d1691667bec17907d03f7a91 100644 (file)
@@ -89,6 +89,19 @@ llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
 }
 
 
+static void
+llvmpipe_set_index_buffer(struct pipe_context *pipe,
+                          const struct pipe_index_buffer *ib)
+{
+   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+   if (ib)
+      memcpy(&llvmpipe->index_buffer, ib, sizeof(llvmpipe->index_buffer));
+   else
+      memset(&llvmpipe->index_buffer, 0, sizeof(llvmpipe->index_buffer));
+
+   /* TODO make this more like a state */
+}
 
 void
 llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe)
@@ -98,4 +111,5 @@ llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe)
    llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
 
    llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
+   llvmpipe->pipe.set_index_buffer = llvmpipe_set_index_buffer;
 }
index 915a925402577bc7f7477b44d201a78530a8e6b4..3fc39c113721cd3e6501b76ba096ba8e4c8c9ba6 100644 (file)
@@ -86,6 +86,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
        nv50->pipe.draw_arrays_instanced = nv50_draw_arrays_instanced;
        nv50->pipe.draw_elements = nv50_draw_elements;
        nv50->pipe.draw_elements_instanced = nv50_draw_elements_instanced;
+       nv50->pipe.draw_vbo = nv50_draw_vbo;
        nv50->pipe.clear = nv50_clear;
 
        nv50->pipe.flush = nv50_flush;
index 12c4a93a9bd4ed2ba1574dfc3c45cc21ec915df2..a7c2b5d4874c0a966d79f824dd07b90315e7eff6 100644 (file)
@@ -148,6 +148,7 @@ struct nv50_context {
        struct pipe_resource *constbuf[PIPE_SHADER_TYPES];
        struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
        unsigned vtxbuf_nr;
+       struct pipe_index_buffer idxbuf;
        struct nv50_vtxelt_stateobj *vtxelt;
        struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS];
        unsigned sampler_nr[3];
@@ -197,6 +198,8 @@ extern void nv50_draw_elements_instanced(struct pipe_context *pipe,
                                         unsigned count,
                                         unsigned startInstance,
                                         unsigned instanceCount);
+extern void nv50_draw_vbo(struct pipe_context *pipe,
+                          const struct pipe_draw_info *info);
 extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso);
 extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50);
 
index 42c5a5831893a8769617defbd3f6380a0b6ac88d..ec0c0ff28388727ec73ea4844098c37b805f168f 100644 (file)
@@ -742,6 +742,20 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
        nv50->dirty |= NV50_NEW_ARRAYS;
 }
 
+static void
+nv50_set_index_buffer(struct pipe_context *pipe,
+                     const struct pipe_index_buffer *ib)
+{
+       struct nv50_context *nv50 = nv50_context(pipe);
+
+       if (ib)
+               memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
+       else
+               memset(&nv50->idxbuf, 0, sizeof(nv50->idxbuf));
+
+       /* TODO make this more like a state */
+}
+
 static void *
 nv50_vtxelts_state_create(struct pipe_context *pipe,
                          unsigned num_elements,
@@ -827,5 +841,6 @@ nv50_init_state_functions(struct nv50_context *nv50)
        nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind;
 
        nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
+       nv50->pipe.set_index_buffer = nv50_set_index_buffer;
 }
 
index 864cb09352a1d4f89b333ceea280af147816fbdd..11ffc182c2da92720dac8d8837a86d9b1147f351 100644 (file)
@@ -473,6 +473,37 @@ nv50_draw_elements(struct pipe_context *pipe,
                                     mode, start, count, 0, 1);
 }
 
+void
+nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+       struct nv50_context *nv50 = nv50_context(pipe);
+
+       if (info->indexed && nv50->idxbuf.buffer) {
+               unsigned offset;
+
+               assert(nv50->idxbuf.offset % nv50->idxbuf.index_size == 0);
+               offset = nv50->idxbuf.offset / nv50->idxbuf.index_size;
+
+               nv50_draw_elements_instanced(pipe,
+                                            nv50->idxbuf.buffer,
+                                            nv50->idxbuf.index_size,
+                                            info->index_bias,
+                                            info->mode,
+                                            info->start + offset,
+                                            info->count,
+                                            info->start_instance,
+                                            info->instance_count);
+       }
+       else {
+               nv50_draw_arrays_instanced(pipe,
+                                          info->mode,
+                                          info->start,
+                                          info->count,
+                                          info->start_instance,
+                                          info->instance_count);
+       }
+}
+
 static INLINE boolean
 nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
                       struct nouveau_stateobj **pso,
index 6d2dc4d5bf6311c0d9277d3c43fc41722dc86fdf..f30795f69af84a5c75702f9e3783abf851f38c09 100644 (file)
@@ -57,6 +57,7 @@ nvfx_create(struct pipe_screen *pscreen, void *priv)
        nvfx->pipe.destroy = nvfx_destroy;
        nvfx->pipe.draw_arrays = nvfx_draw_arrays;
        nvfx->pipe.draw_elements = nvfx_draw_elements;
+       nvfx->pipe.draw_vbo = nvfx_draw_vbo;
        nvfx->pipe.clear = nvfx_clear;
        nvfx->pipe.flush = nvfx_flush;
 
index e48f9f3aa88d2a537c998acbffebeb2e1e145ba9..d6cd272eed51a939e4f65dd0447f26e9076fcec9 100644 (file)
@@ -121,7 +121,8 @@ struct nvfx_context {
        struct pipe_stencil_ref stencil_ref;
        struct pipe_viewport_state viewport;
        struct pipe_framebuffer_state framebuffer;
-       struct pipe_resource *idxbuf;
+       struct pipe_index_buffer idxbuf;
+       struct pipe_resource *idxbuf_buffer;
        unsigned idxbuf_format;
        struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
        struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
@@ -242,6 +243,8 @@ extern void nvfx_draw_elements(struct pipe_context *pipe,
                                unsigned indexSize, int indexBias,
                                unsigned mode, unsigned start,
                                unsigned count);
+extern void nvfx_draw_vbo(struct pipe_context *pipe,
+                          const struct pipe_draw_info *info);
 
 /* nvfx_vertprog.c */
 extern boolean nvfx_vertprog_validate(struct nvfx_context *nvfx);
index 30322d46d934df0a1e8867f41408aaac2f4ce265..cd58e439d711e6fbb98e7612a5debfc27a3c154b 100644 (file)
@@ -555,6 +555,20 @@ nvfx_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
        nvfx->draw_dirty |= NVFX_NEW_ARRAYS;
 }
 
+static void
+nvfx_set_index_buffer(struct pipe_context *pipe,
+                     const struct pipe_index_buffer *ib)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+
+       if (ib)
+               memcpy(&nvfx->idxbuf, ib, sizeof(nvfx->idxbuf));
+       else
+               memset(&nvfx->idxbuf, 0, sizeof(nvfx->idxbuf));
+
+       /* TODO make this more like a state */
+}
+
 static void *
 nvfx_vtxelts_state_create(struct pipe_context *pipe,
                          unsigned num_elements,
@@ -635,4 +649,5 @@ nvfx_init_state_functions(struct nvfx_context *nvfx)
        nvfx->pipe.bind_vertex_elements_state = nvfx_vtxelts_state_bind;
 
        nvfx->pipe.set_vertex_buffers = nvfx_set_vertex_buffers;
+       nvfx->pipe.set_index_buffer = nvfx_set_index_buffer;
 }
index 520bae5aed2b82fd3a89598a71884219531407c1..23a59b589b90e75a1fb31db76936e92e91004a38 100644 (file)
@@ -85,7 +85,7 @@ nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib,
        unsigned type;
 
        if (!ib) {
-               nvfx->idxbuf = NULL;
+               nvfx->idxbuf_buffer = NULL;
                nvfx->idxbuf_format = 0xdeadbeef;
                return FALSE;
        }
@@ -104,10 +104,10 @@ nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib,
                return FALSE;
        }
 
-       if (ib != nvfx->idxbuf ||
+       if (ib != nvfx->idxbuf_buffer ||
            type != nvfx->idxbuf_format) {
                nvfx->dirty |= NVFX_NEW_ARRAYS;
-               nvfx->idxbuf = ib;
+               nvfx->idxbuf_buffer = ib;
                nvfx->idxbuf_format = type;
        }
 
@@ -491,11 +491,38 @@ nvfx_draw_elements(struct pipe_context *pipe,
        pipe->flush(pipe, 0, NULL);
 }
 
+void
+nvfx_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+       struct nvfx_context *nvfx = nvfx_context(pipe);
+
+       if (info->indexed && nvfx->idxbuf.buffer) {
+               unsigned offset;
+
+               assert(nvfx->idxbuf.offset % nvfx->idxbuf.index_size == 0);
+               offset = nvfx->idxbuf.offset / nvfx->idxbuf.index_size;
+
+               nvfx_draw_elements(pipe,
+                                  nvfx->idxbuf.buffer,
+                                  nvfx->idxbuf.index_size,
+                                  info->index_bias,
+                                  info->mode,
+                                  info->start + offset,
+                                  info->count);
+       }
+       else {
+               nvfx_draw_arrays(pipe,
+                               info->mode,
+                               info->start,
+                               info->count);
+       }
+}
+
 boolean
 nvfx_vbo_validate(struct nvfx_context *nvfx)
 {
        struct nouveau_channel* chan = nvfx->screen->base.channel;
-       struct pipe_resource *ib = nvfx->idxbuf;
+       struct pipe_resource *ib = nvfx->idxbuf_buffer;
        unsigned ib_format = nvfx->idxbuf_format;
        int i;
        int elements = MAX2(nvfx->vtxelt->num_elements, nvfx->hw_vtxelt_nr);
@@ -610,10 +637,10 @@ nvfx_vbo_relocate(struct nvfx_context *nvfx)
                }
        }
 
-       if(nvfx->idxbuf)
+       if(nvfx->idxbuf_buffer)
        {
                unsigned ib_flags = nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
-               struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf)->bo;
+               struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf_buffer)->bo;
 
                assert(nvfx->screen->index_buffer_reloc_flags);
 
index b4256c62786e47ab6f493742cd1a9de95fbda17b..7c77a46016d7def2da133ad7a987fa118e5a364f 100644 (file)
@@ -524,6 +524,8 @@ struct r300_context {
     struct r300_vertex_element_state *velems;
     bool any_user_vbs;
 
+    struct pipe_index_buffer index_buffer;
+
     /* Vertex info for Draw. */
     struct vertex_info vertex_info;
 
index bae02135da9d18550502cbd5408e552097473443..da96098cc44ca36112f5344448bdd2cb9efb86e9 100644 (file)
@@ -33,6 +33,7 @@
 #include "util/u_memory.h"
 #include "util/u_upload_mgr.h"
 #include "util/u_prim.h"
+#include "util/u_draw_quad.h"
 
 #include "r300_cs.h"
 #include "r300_context.h"
@@ -638,26 +639,56 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
     }
 }
 
+static void r300_draw_vbo(struct pipe_context* pipe,
+                          const struct pipe_draw_info *info)
+{
+    struct r300_context* r300 = r300_context(pipe);
+
+    if (info->indexed && r300->index_buffer.buffer) {
+        unsigned offset;
+
+        assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0);
+        offset = r300->index_buffer.offset / r300->index_buffer.index_size;
+
+        r300_draw_range_elements(pipe,
+                                 r300->index_buffer.buffer,
+                                 r300->index_buffer.index_size,
+                                 info->index_bias,
+                                 info->min_index,
+                                 info->max_index,
+                                 info->mode,
+                                 info->start + offset,
+                                 info->count);
+    }
+    else {
+        r300_draw_arrays(pipe,
+                         info->mode,
+                         info->start,
+                         info->count);
+    }
+}
+
 /****************************************************************************
  * The rest of this file is for SW TCL rendering only. Please be polite and *
  * keep these functions separated so that they are easier to locate. ~C.    *
  ***************************************************************************/
 
-/* SW TCL arrays, using Draw. */
-static void r300_swtcl_draw_arrays(struct pipe_context* pipe,
-                                   unsigned mode,
-                                   unsigned start,
-                                   unsigned count)
+/* SW TCL elements, using Draw. */
+static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
+                                const struct pipe_draw_info *info)
 {
     struct r300_context* r300 = r300_context(pipe);
     struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
+    struct pipe_transfer *ib_transfer;
+    unsigned count = info->count;
     int i;
+    void* indices = NULL;
 
     if (r300->skip_rendering) {
         return;
     }
 
-    if (!u_trim_pipe_prim(mode, &count)) {
+    if (!u_trim_pipe_prim(info->mode, &count)) {
         return;
     }
 
@@ -667,13 +698,25 @@ static void r300_swtcl_draw_arrays(struct pipe_context* pipe,
         void* buf = pipe_buffer_map(pipe,
                                     r300->vertex_buffer[i].buffer,
                                     PIPE_TRANSFER_READ,
-                                   &vb_transfer[i]);
+                                    &vb_transfer[i]);
         draw_set_mapped_vertex_buffer(r300->draw, i, buf);
     }
 
-    draw_set_mapped_element_buffer(r300->draw, 0, 0, NULL);
+    if (info->indexed && r300->index_buffer.buffer) {
+        indices = pipe_buffer_map(pipe, r300->index_buffer.buffer,
+                                  PIPE_TRANSFER_READ, &ib_transfer);
+        if (indices)
+            indices += r300->index_buffer.offset;
+    }
+
+    draw_set_mapped_element_buffer_range(r300->draw, (indices) ?
+                                         r300->index_buffer.index_size : 0,
+                                         info->index_bias,
+                                         info->min_index,
+                                         info->max_index,
+                                         indices);
 
-    draw_arrays(r300->draw, mode, start, count);
+    draw_arrays(r300->draw, info->mode, info->start, count);
 
     /* XXX Not sure whether this is the best fix.
      * It prevents CS from being rejected and weird assertion failures. */
@@ -681,9 +724,15 @@ static void r300_swtcl_draw_arrays(struct pipe_context* pipe,
 
     for (i = 0; i < r300->vertex_buffer_count; i++) {
         pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
-                         vb_transfer[i]);
+                          vb_transfer[i]);
         draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
     }
+
+    if (ib_transfer) {
+        pipe_buffer_unmap(pipe, r300->index_buffer.buffer, ib_transfer);
+        draw_set_mapped_element_buffer_range(r300->draw, 0, 0, info->start,
+                info->start + count - 1, NULL);
+    }
 }
 
 /* SW TCL elements, using Draw. */
@@ -698,51 +747,40 @@ static void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
                                            unsigned count)
 {
     struct r300_context* r300 = r300_context(pipe);
-    struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
-    struct pipe_transfer *ib_transfer;
-    int i;
-    void* indices;
-
-    if (r300->skip_rendering) {
-        return;
-    }
-
-    if (!u_trim_pipe_prim(mode, &count)) {
-        return;
+    struct pipe_draw_info info;
+    struct pipe_index_buffer saved_ib, ib;
+
+    util_draw_init_info(&info);
+    info.mode = mode;
+    info.start = start;
+    info.count = count;
+    info.index_bias = indexBias;
+    info.min_index = minIndex;
+    info.max_index = maxIndex;
+
+    if (indexBuffer) {
+       info.indexed = TRUE;
+
+       saved_ib = r300->index_buffer;
+       ib.buffer = indexBuffer;
+       ib.offset = 0;
+       ib.index_size = indexSize;
+       pipe->set_index_buffer(pipe, &ib);
     }
 
-    r300_update_derived_state(r300);
-
-    for (i = 0; i < r300->vertex_buffer_count; i++) {
-        void* buf = pipe_buffer_map(pipe,
-                                    r300->vertex_buffer[i].buffer,
-                                    PIPE_TRANSFER_READ,
-                                   &vb_transfer[i]);
-        draw_set_mapped_vertex_buffer(r300->draw, i, buf);
-    }
-
-    indices = pipe_buffer_map(pipe, indexBuffer,
-                              PIPE_TRANSFER_READ, &ib_transfer);
-    draw_set_mapped_element_buffer_range(r300->draw, indexSize, indexBias,
-                                         minIndex, maxIndex, indices);
-
-    draw_arrays(r300->draw, mode, start, count);
-
-    /* XXX Not sure whether this is the best fix.
-     * It prevents CS from being rejected and weird assertion failures. */
-    draw_flush(r300->draw);
+    r300_swtcl_draw_vbo(pipe, &info);
 
-    for (i = 0; i < r300->vertex_buffer_count; i++) {
-        pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
-                         vb_transfer[i]);
-        draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
-    }
+    if (indexBuffer)
+       pipe->set_index_buffer(pipe, &saved_ib);
+}
 
-    pipe_buffer_unmap(pipe, indexBuffer,
-                     ib_transfer);
-    draw_set_mapped_element_buffer_range(r300->draw, 0, 0,
-                                         start, start + count - 1,
-                                         NULL);
+static void r300_swtcl_draw_arrays(struct pipe_context* pipe,
+                                   unsigned mode,
+                                   unsigned start,
+                                   unsigned count)
+{
+   r300_swtcl_draw_range_elements(pipe, NULL, 0, 0,
+           start, start + count -1, mode, start, count);
 }
 
 /* Object for rendering using Draw. */
@@ -1148,9 +1186,11 @@ void r300_init_render_functions(struct r300_context *r300)
     if (r300->screen->caps.has_tcl) {
         r300->context.draw_arrays = r300_draw_arrays;
         r300->context.draw_range_elements = r300_draw_range_elements;
+        r300->context.draw_vbo = r300_draw_vbo;
     } else {
         r300->context.draw_arrays = r300_swtcl_draw_arrays;
         r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
+        r300->context.draw_vbo = r300_swtcl_draw_vbo;
     }
 
     r300->context.resource_resolve = r300_resource_resolve;
index 9a6b4e12ff1ed0c135c91d8b8a23ef5cc4e20cc7..6d801cf1594145ba4ecff460d208a37c8fb28819 100644 (file)
@@ -42,6 +42,9 @@ struct r300_stencilref_context {
         unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex,
         unsigned mode, unsigned start, unsigned count);
 
+    void (*draw_vbo)(struct pipe_context *pipe,
+                     const struct pipe_draw_info *info);
+
     uint32_t rs_cull_mode;
     uint32_t zb_stencilrefmask;
     ubyte ref_value_front;
@@ -144,6 +147,23 @@ static void r300_stencilref_draw_range_elements(
     }
 }
 
+static void r300_stencilref_draw_vbo(struct pipe_context *pipe,
+                                     const struct pipe_draw_info *info)
+{
+    struct r300_context *r300 = r300_context(pipe);
+    struct r300_stencilref_context *sr = r300->stencilref_fallback;
+
+    if (!r300_stencilref_needed(r300)) {
+        sr->draw_vbo(pipe, info);
+    } else {
+        r300_stencilref_begin(r300);
+        sr->draw_vbo(pipe, info);
+        r300_stencilref_switch_side(r300);
+        sr->draw_vbo(pipe, info);
+        r300_stencilref_end(r300);
+    }
+}
+
 void r300_plug_in_stencil_ref_fallback(struct r300_context *r300)
 {
     r300->stencilref_fallback = CALLOC_STRUCT(r300_stencilref_context);
@@ -151,8 +171,10 @@ void r300_plug_in_stencil_ref_fallback(struct r300_context *r300)
     /* Save original draw functions. */
     r300->stencilref_fallback->draw_arrays = r300->context.draw_arrays;
     r300->stencilref_fallback->draw_range_elements = r300->context.draw_range_elements;
+    r300->stencilref_fallback->draw_vbo = r300->context.draw_vbo;
 
     /* Override the draw functions. */
     r300->context.draw_arrays = r300_stencilref_draw_arrays;
     r300->context.draw_range_elements = r300_stencilref_draw_range_elements;
+    r300->context.draw_vbo = r300_stencilref_draw_vbo;
 }
index 3e221f2e02de0d781fff819abf1c1dbf6200e724..bccd7d78591b0473e2d4f481585affc4604bfb1c 100644 (file)
@@ -1505,6 +1505,23 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
     r300->vertex_buffer_count = count;
 }
 
+static void r300_set_index_buffer(struct pipe_context* pipe,
+                                  const struct pipe_index_buffer *ib)
+{
+    struct r300_context* r300 = r300_context(pipe);
+
+    if (ib) {
+        pipe_resource_reference(&r300->index_buffer.buffer, ib->buffer);
+        memcpy(&r300->index_buffer, ib, sizeof(r300->index_buffer));
+    }
+    else {
+        pipe_resource_reference(&r300->index_buffer.buffer, NULL);
+        memset(&r300->index_buffer, 0, sizeof(r300->index_buffer));
+    }
+
+    /* TODO make this more like a state */
+}
+
 /* Initialize the PSC tables. */
 static void r300_vertex_psc(struct r300_vertex_element_state *velems)
 {
@@ -1852,6 +1869,7 @@ void r300_init_state_functions(struct r300_context* r300)
     r300->context.set_viewport_state = r300_set_viewport_state;
 
     r300->context.set_vertex_buffers = r300_set_vertex_buffers;
+    r300->context.set_index_buffer = r300_set_index_buffer;
 
     r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
     r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;
index 4c7b67ea52c8e0d7cd52cda3e1da334edf56222c..2c2bd4672befc7ab6a795b18ffdb95e83a9d0710 100644 (file)
@@ -316,6 +316,7 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
        rctx->context.draw_arrays = r600_draw_arrays;
        rctx->context.draw_elements = r600_draw_elements;
        rctx->context.draw_range_elements = r600_draw_range_elements;
+       rctx->context.draw_vbo = r600_draw_vbo;
        rctx->context.flush = r600_flush;
 
        /* Easy accessing of screen/winsys. */
index 1f03b202eecdc6d7ff3e83069f965b8751771286..9427c19d059641e6456c9c8ebf23a7e530e68961 100644 (file)
@@ -157,6 +157,7 @@ struct r600_context {
        struct r600_context_state       *vs_sampler_view[PIPE_MAX_ATTRIBS];
        struct r600_vertex_element      *vertex_elements;
        struct pipe_vertex_buffer       vertex_buffer[PIPE_MAX_ATTRIBS];
+       struct pipe_index_buffer        index_buffer;
 };
 
 #if 0
@@ -201,6 +202,8 @@ void r600_draw_range_elements(struct pipe_context *ctx,
                unsigned index_size, int index_bias, unsigned min_index,
                unsigned max_index, unsigned mode,
                unsigned start, unsigned count);
+void r600_draw_vbo(struct pipe_context *ctx,
+                   const struct pipe_draw_info *info);
 
 void r600_init_blit_functions(struct r600_context *rctx);
 void r600_init_state_functions(struct r600_context *rctx);
index b248beaf8c69ea9302bca5e2ca87c353857153e7..eeaa677edbd05dc315e3ce0693d5003b2184b908 100644 (file)
@@ -225,3 +225,30 @@ void r600_draw_arrays(struct pipe_context *ctx, unsigned mode,
        draw.index_buffer = NULL;
        r600_draw_common(&draw);
 }
+
+void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       struct r600_draw draw;
+
+       assert(info->index_bias == 0);
+
+       draw.ctx = ctx;
+       draw.mode = info->mode;
+       draw.start = info->start;
+       draw.count = info->count;
+       if (info->indexed && rctx->index_buffer.buffer) {
+               draw.index_size = rctx->index_buffer.index_size;
+               draw.index_buffer = rctx->index_buffer.buffer;
+
+               assert(rctx->index_buffer.offset %
+                               rctx->index_buffer.index_size == 0);
+               draw.start += rctx->index_buffer.offset /
+                       rctx->index_buffer.index_size;
+       }
+       else {
+               draw.index_size = 0;
+               draw.index_buffer = NULL;
+       }
+       r600_draw_common(&draw);
+}
index ff5df855c6264aa049cc3bbcadaa52d0e9118d40..57879e8d8b8704bbf6410c335afde201eee873dc 100644 (file)
@@ -404,6 +404,23 @@ static void r600_set_vertex_buffers(struct pipe_context *ctx,
        rctx->nvertex_buffer = count;
 }
 
+static void r600_set_index_buffer(struct pipe_context *ctx,
+                                 const struct pipe_index_buffer *ib)
+{
+       struct r600_context *rctx = r600_context(ctx);
+
+       if (ib) {
+               pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer);
+               memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer));
+       }
+       else {
+               pipe_resource_reference(&rctx->index_buffer.buffer, NULL);
+               memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer));
+       }
+
+       /* TODO make this more like a state */
+}
+
 static void r600_set_viewport_state(struct pipe_context *ctx,
                                        const struct pipe_viewport_state *state)
 {
@@ -449,6 +466,7 @@ void r600_init_state_functions(struct r600_context *rctx)
        rctx->context.set_scissor_state = r600_set_scissor_state;
        rctx->context.set_stencil_ref = r600_set_stencil_ref;
        rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
+       rctx->context.set_index_buffer = r600_set_index_buffer;
        rctx->context.set_vertex_sampler_views = r600_set_vs_sampler_view;
        rctx->context.set_viewport_state = r600_set_viewport_state;
        rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
index e0dd5cf8c2b17a226a229b233e40279ace9ff8b0..c748073b2a2b0cffdb96339edc1175f71e5f7b3b 100644 (file)
@@ -185,6 +185,21 @@ rbug_draw_range_elements(struct pipe_context *_pipe,
    pipe_mutex_unlock(rb_pipe->draw_mutex);
 }
 
+static void
+rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info)
+{
+   struct rbug_context *rb_pipe = rbug_context(_pipe);
+   struct pipe_context *pipe = rb_pipe->pipe;
+
+   pipe_mutex_lock(rb_pipe->draw_mutex);
+   rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE);
+
+   pipe->draw_vbo(pipe, info);
+
+   rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER);
+   pipe_mutex_unlock(rb_pipe->draw_mutex);
+}
+
 static struct pipe_query *
 rbug_create_query(struct pipe_context *_pipe,
                   unsigned query_type)
@@ -744,6 +759,23 @@ rbug_set_vertex_buffers(struct pipe_context *_pipe,
                             buffers);
 }
 
+static void
+rbug_set_index_buffer(struct pipe_context *_pipe,
+                      const struct pipe_index_buffer *_ib)
+{
+   struct rbug_context *rb_pipe = rbug_context(_pipe);
+   struct pipe_context *pipe = rb_pipe->pipe;
+   struct pipe_index_buffer unwrapped_ib, *ib = NULL;
+
+   if (_ib) {
+      unwrapped_ib = *_ib;
+      unwrapped_ib.buffer = rbug_resource_unwrap(_ib->buffer);
+      ib = &unwrapped_ib;
+   }
+
+   pipe->set_index_buffer(pipe, ib);
+}
+
 static void
 rbug_set_sample_mask(struct pipe_context *_pipe,
                      unsigned sample_mask)
@@ -1043,6 +1075,7 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    rb_pipe->base.draw_arrays = rbug_draw_arrays;
    rb_pipe->base.draw_elements = rbug_draw_elements;
    rb_pipe->base.draw_range_elements = rbug_draw_range_elements;
+   rb_pipe->base.draw_vbo = rbug_draw_vbo;
    rb_pipe->base.create_query = rbug_create_query;
    rb_pipe->base.destroy_query = rbug_destroy_query;
    rb_pipe->base.begin_query = rbug_begin_query;
@@ -1084,6 +1117,7 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
    rb_pipe->base.set_fragment_sampler_views = rbug_set_fragment_sampler_views;
    rb_pipe->base.set_vertex_sampler_views = rbug_set_vertex_sampler_views;
    rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers;
+   rb_pipe->base.set_index_buffer = rbug_set_index_buffer;
    rb_pipe->base.set_sample_mask = rbug_set_sample_mask;
    rb_pipe->base.resource_copy_region = rbug_resource_copy_region;
    rb_pipe->base.clear = rbug_clear;
index 12ef98aac7589d13cfba4583a67df53d2bf737df..fa1fae6f006a15e8f611e92c49db167e284f2731 100644 (file)
@@ -282,12 +282,14 @@ softpipe_create_context( struct pipe_screen *screen,
    softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
    softpipe->pipe.set_stream_output_buffers = softpipe_set_stream_output_buffers;
    softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;
+   softpipe->pipe.set_index_buffer = softpipe_set_index_buffer;
 
    softpipe->pipe.draw_arrays = softpipe_draw_arrays;
    softpipe->pipe.draw_elements = softpipe_draw_elements;
    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_vbo = softpipe_draw_vbo;
    softpipe->pipe.draw_stream_output = softpipe_draw_stream_output;
 
    softpipe->pipe.clear = softpipe_clear;
index 53115a827d01e9d4617e771ef65471fb27bb3c41..c5f53cfa61a5d31a929e3c2cb6229ada9a6f41b4 100644 (file)
@@ -82,6 +82,7 @@ struct softpipe_context {
    struct pipe_sampler_view *geometry_sampler_views[PIPE_MAX_GEOMETRY_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+   struct pipe_index_buffer index_buffer;
    struct {
       struct softpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
       int offset[PIPE_MAX_SO_BUFFERS];
index 9e727c93811f7b0e7ba4f744df3c00465242d184..2855f55a0e160828244baf4db68836246d7848c8 100644 (file)
@@ -35,6 +35,7 @@
 #include "pipe/p_context.h"
 #include "util/u_inlines.h"
 #include "util/u_prim.h"
+#include "util/u_draw_quad.h"
 
 #include "sp_context.h"
 #include "sp_query.h"
@@ -111,27 +112,19 @@ softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode)
  * When the min/max element indexes aren't known, minIndex should be 0
  * and maxIndex should be ~0.
  */
-static void
-softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
-                                       struct pipe_resource *indexBuffer,
-                                       unsigned indexSize,
-                                       int indexBias,
-                                       unsigned minIndex,
-                                       unsigned maxIndex,
-                                       unsigned mode,
-                                       unsigned start,
-                                       unsigned count,
-                                       unsigned startInstance,
-                                       unsigned instanceCount)
+void
+softpipe_draw_vbo(struct pipe_context *pipe,
+                  const struct pipe_draw_info *info)
 {
    struct softpipe_context *sp = softpipe_context(pipe);
    struct draw_context *draw = sp->draw;
+   void *mapped_indices = NULL;
    unsigned i;
 
    if (!softpipe_check_render_cond(sp))
       return;
 
-   sp->reduced_api_prim = u_reduced_prim(mode);
+   sp->reduced_api_prim = u_reduced_prim(info->mode);
 
    if (sp->dirty) {
       softpipe_update_derived(sp);
@@ -146,31 +139,27 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
    }
 
    /* Map index buffer, if present */
-   if (indexBuffer) {
-      void *mapped_indexes = softpipe_resource(indexBuffer)->data;
-      draw_set_mapped_element_buffer_range(draw,
-                                           indexSize,
-                                           indexBias,
-                                           minIndex,
-                                           maxIndex,
-                                           mapped_indexes);
-   } else {
-      /* no index/element buffer */
-      draw_set_mapped_element_buffer_range(draw,
-                                           0, 0,
-                                           start,
-                                           start + count - 1,
-                                           NULL);
+   if (info->indexed && sp->index_buffer.buffer) {
+      mapped_indices = softpipe_resource(sp->index_buffer.buffer)->data;
+      mapped_indices += sp->index_buffer.offset;
    }
 
+   draw_set_mapped_element_buffer_range(draw, (mapped_indices) ?
+                                        sp->index_buffer.index_size : 0,
+                                        info->index_bias,
+                                        info->min_index,
+                                        info->max_index,
+                                        mapped_indices);
+
    /* draw! */
-   draw_arrays_instanced(draw, mode, start, count, startInstance, instanceCount);
+   draw_arrays_instanced(draw, info->mode, info->start, info->count,
+         info->start_instance, info->instance_count);
 
    /* unmap vertex/index buffers - will cause draw module to flush */
    for (i = 0; i < sp->num_vertex_buffers; i++) {
       draw_set_mapped_vertex_buffer(draw, i, NULL);
    }
-   if (indexBuffer) {
+   if (mapped_indices) {
       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
    }
 
@@ -185,6 +174,49 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
    sp->dirty_render_cache = TRUE;
 }
 
+static void
+softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
+                                       struct pipe_resource *indexBuffer,
+                                       unsigned indexSize,
+                                       int indexBias,
+                                       unsigned minIndex,
+                                       unsigned maxIndex,
+                                       unsigned mode,
+                                       unsigned start,
+                                       unsigned count,
+                                       unsigned startInstance,
+                                       unsigned instanceCount)
+{
+   struct softpipe_context *sp = softpipe_context(pipe);
+   struct pipe_draw_info info;
+   struct pipe_index_buffer saved_ib, ib;
+
+   util_draw_init_info(&info);
+   info.mode = mode;
+   info.start = start;
+   info.count = count;
+   info.start_instance = startInstance;
+   info.instance_count = instanceCount;
+   info.index_bias = indexBias;
+   info.min_index = minIndex;
+   info.max_index = maxIndex;
+
+   if (indexBuffer) {
+      info.indexed = TRUE;
+
+      saved_ib = sp->index_buffer;
+      ib.buffer = indexBuffer;
+      ib.offset = 0;
+      ib.index_size = indexSize;
+      pipe->set_index_buffer(pipe, &ib);
+   }
+
+   softpipe_draw_vbo(pipe, &info);
+
+   if (indexBuffer)
+      pipe->set_index_buffer(pipe, &saved_ib);
+}
+
 
 void
 softpipe_draw_range_elements(struct pipe_context *pipe,
index 7d6b86dce0485406ff8f2bc034fce0cc62753496..f04b0a5d31e1314fd7ad91a022dda16b46f98182 100644 (file)
@@ -221,6 +221,9 @@ void softpipe_set_vertex_buffers(struct pipe_context *,
                                  unsigned count,
                                  const struct pipe_vertex_buffer *);
 
+void softpipe_set_index_buffer(struct pipe_context *,
+                               const struct pipe_index_buffer *);
+
 
 void softpipe_update_derived( struct softpipe_context *softpipe );
 
@@ -260,6 +263,10 @@ softpipe_draw_elements_instanced(struct pipe_context *pipe,
                                  unsigned startInstance,
                                  unsigned instanceCount);
 
+void
+softpipe_draw_vbo(struct pipe_context *pipe,
+                  const struct pipe_draw_info *info);
+
 void softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode);
 
 void
index 462f4d2655ef7ba75c0a7189c4bddcbb63486ba7..880a7c7cd2642151f0c545863599289099cbbc2f 100644 (file)
@@ -88,3 +88,17 @@ softpipe_set_vertex_buffers(struct pipe_context *pipe,
 
    draw_set_vertex_buffers(softpipe->draw, count, buffers);
 }
+
+void
+softpipe_set_index_buffer(struct pipe_context *pipe,
+                          const struct pipe_index_buffer *ib)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+
+   if (ib)
+      memcpy(&softpipe->index_buffer, ib, sizeof(softpipe->index_buffer));
+   else
+      memset(&softpipe->index_buffer, 0, sizeof(softpipe->index_buffer));
+
+   /* TODO make this more like a state */
+}
index 9a46de643fd20b1c1d159a7996b5ca63390506bf..67a7614c8afaa5a09f3e5dcc944eec44cff0ddfc 100644 (file)
@@ -190,6 +190,7 @@ struct svga_state
    struct svga_vertex_shader *vs;
 
    struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
+   struct pipe_index_buffer ib;
    struct pipe_resource *cb[PIPE_SHADER_TYPES];
 
    struct pipe_framebuffer_state framebuffer;
index 58e930d98355f45a2ba81253423289db061741cb..fceaa83d70187c6deb364678159c0ac4bd6ad0a6 100644 (file)
@@ -248,10 +248,34 @@ svga_draw_arrays( struct pipe_context *pipe,
                             start, count);
 }
 
+static void
+svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   if (info->indexed && svga->curr.ib.buffer) {
+      unsigned offset;
+
+      assert(svga->curr.ib.offset % svga->curr.ib.index_size == 0);
+      offset = svga->curr.ib.offset / svga->curr.ib.index_size;
+
+      svga_draw_range_elements(pipe, svga->curr.ib.buffer,
+                               svga->curr.ib.index_size, info->index_bias,
+                               info->min_index, info->max_index,
+                               info->mode, info->start + offset, info->count);
+   }
+   else {
+      svga_draw_range_elements(pipe, NULL, 0, 0,
+                               info->min_index, info->max_index,
+                               info->mode, info->start, info->count);
+   }
+}
+
 
 void svga_init_draw_functions( struct svga_context *svga )
 {
    svga->pipe.draw_arrays = svga_draw_arrays;
    svga->pipe.draw_elements = svga_draw_elements;
    svga->pipe.draw_range_elements = svga_draw_range_elements;
+   svga->pipe.draw_vbo = svga_draw_vbo;
 }
index 23808ad08e093ee532af9c58aac2aba86f05cc39..86c79459f3e51c3c31e2d1d615da1e491c541a29 100644 (file)
@@ -66,6 +66,24 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
 }
 
 
+static void svga_set_index_buffer(struct pipe_context *pipe,
+                                  const struct pipe_index_buffer *ib)
+{
+   struct svga_context *svga = svga_context(pipe);
+
+   if (ib) {
+      pipe_resource_reference(&svga->curr.ib.buffer, ib->buffer);
+      memcpy(&svga->curr.ib, ib, sizeof(svga->curr.ib));
+   }
+   else {
+      pipe_resource_reference(&svga->curr.ib.buffer, NULL);
+      memset(&svga->curr.ib, 0, sizeof(svga->curr.ib));
+   }
+
+   /* TODO make this more like a state */
+}
+
+
 static void *
 svga_create_vertex_elements_state(struct pipe_context *pipe,
                                   unsigned count,
@@ -109,6 +127,7 @@ void svga_cleanup_vertex_state( struct svga_context *svga )
 void svga_init_vertex_functions( struct svga_context *svga )
 {
    svga->pipe.set_vertex_buffers = svga_set_vertex_buffers;
+   svga->pipe.set_index_buffer = svga_set_index_buffer;
    svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state;
    svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state;
    svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state;
index 55dd6cf8837396d6833840e6be7cbb4ba8a0d01e..91c9bf09999abb0c650e28475698c44891471da7 100644 (file)
@@ -167,6 +167,32 @@ trace_context_draw_range_elements(struct pipe_context *_pipe,
 }
 
 
+static INLINE void
+trace_context_draw_vbo(struct pipe_context *_pipe,
+                       const struct pipe_draw_info *info)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct pipe_context *pipe = tr_ctx->pipe;
+
+   trace_dump_call_begin("pipe_context", "draw_vbo");
+
+   trace_dump_arg(ptr,  pipe);
+   trace_dump_arg(bool, info->indexed);
+   trace_dump_arg(uint, info->mode);
+   trace_dump_arg(uint, info->start);
+   trace_dump_arg(uint, info->count);
+   trace_dump_arg(uint, info->start_instance);
+   trace_dump_arg(uint, info->instance_count);
+   trace_dump_arg(int,  info->index_bias);
+   trace_dump_arg(uint, info->min_index);
+   trace_dump_arg(uint, info->max_index);
+
+   pipe->draw_vbo(pipe, info);
+
+   trace_dump_call_end();
+}
+
+
 static INLINE struct pipe_query *
 trace_context_create_query(struct pipe_context *_pipe,
                            unsigned query_type)
@@ -1044,6 +1070,30 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe,
 }
 
 
+static INLINE void
+trace_context_set_index_buffer(struct pipe_context *_pipe,
+                               const struct pipe_index_buffer *_ib)
+{
+   struct trace_context *tr_ctx = trace_context(_pipe);
+   struct pipe_context *pipe = tr_ctx->pipe;
+   struct pipe_index_buffer unwrapped_ib, *ib = NULL;
+
+   if (_ib) {
+      unwrapped_ib = *_ib;
+      unwrapped_ib.buffer = trace_resource_unwrap(tr_ctx, _ib->buffer);
+      ib = &unwrapped_ib;
+   }
+
+   trace_dump_call_begin("pipe_context", "set_index_buffer");
+
+   trace_dump_arg(ptr, pipe);
+   trace_dump_arg(index_buffer, ib);
+
+   pipe->set_index_buffer(pipe, ib);
+
+   trace_dump_call_end();
+}
+
 static INLINE void
 trace_context_resource_copy_region(struct pipe_context *_pipe,
                                    struct pipe_resource *dst,
@@ -1436,6 +1486,7 @@ trace_context_create(struct trace_screen *tr_scr,
    tr_ctx->base.draw_arrays = trace_context_draw_arrays;
    tr_ctx->base.draw_elements = trace_context_draw_elements;
    tr_ctx->base.draw_range_elements = trace_context_draw_range_elements;
+   tr_ctx->base.draw_vbo = trace_context_draw_vbo;
    tr_ctx->base.create_query = trace_context_create_query;
    tr_ctx->base.destroy_query = trace_context_destroy_query;
    tr_ctx->base.begin_query = trace_context_begin_query;
@@ -1477,6 +1528,7 @@ trace_context_create(struct trace_screen *tr_scr,
    tr_ctx->base.create_sampler_view = trace_create_sampler_view;
    tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy;
    tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
+   tr_ctx->base.set_index_buffer = trace_context_set_index_buffer;
    tr_ctx->base.resource_copy_region = trace_context_resource_copy_region;
    tr_ctx->base.clear = trace_context_clear;
    tr_ctx->base.clear_render_target = trace_context_clear_render_target;
index 1727c2a02069538c54945a6d70197a0daa710ebd..bd9a9bfaf16cea9a853b106240899d8eae541705 100644 (file)
@@ -533,6 +533,26 @@ void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state)
 }
 
 
+void trace_dump_index_buffer(const struct pipe_index_buffer *state)
+{
+   if (!trace_dumping_enabled_locked())
+      return;
+
+   if(!state) {
+      trace_dump_null();
+      return;
+   }
+
+   trace_dump_struct_begin("pipe_index_buffer");
+
+   trace_dump_member(uint, state, index_size);
+   trace_dump_member(uint, state, offset);
+   trace_dump_member(resource_ptr, state, buffer);
+
+   trace_dump_struct_end();
+}
+
+
 void trace_dump_vertex_element(const struct pipe_vertex_element *state)
 {
    if (!trace_dumping_enabled_locked())
index e614e8355e3f314905feca7e9122e4222c9d2029..2e70f4e1c74230e71a2a30050662c9f7e9d0e221 100644 (file)
@@ -75,6 +75,8 @@ void trace_dump_transfer(const struct pipe_transfer *state);
 
 void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state);
 
+void trace_dump_index_buffer(const struct pipe_index_buffer *state);
+
 void trace_dump_vertex_element(const struct pipe_vertex_element *state);