Merge branch 'gallium-index-bias'
authorJosé Fonseca <jfonseca@vmware.com>
Tue, 20 Apr 2010 09:07:08 +0000 (11:07 +0200)
committerJosé Fonseca <jfonseca@vmware.com>
Tue, 20 Apr 2010 09:07:08 +0000 (11:07 +0200)
1  2 
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_context.h
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt.c
src/gallium/drivers/i915/i915_context.c
src/gallium/drivers/nvfx/nvfx_vbo.c
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/svga/svga_swtnl_draw.c
src/mesa/state_tracker/st_draw_feedback.c

index d490d3325c26b78c7b86976313926ee30b41ecb6,b6c558ba9b14159bb6d57c670fd0d0d44e2db3a8..4196f01e0b2b6c2aa57295a2065cfdf3b8355747
    */
  
  
 +#include "pipe/p_context.h"
  #include "util/u_memory.h"
  #include "util/u_math.h"
  #include "draw_context.h"
  #include "draw_vs.h"
  #include "draw_gs.h"
  
 +#if HAVE_LLVM
 +#include "gallivm/lp_bld_init.h"
 +#endif
  
 -struct draw_context *draw_create( void )
 +struct draw_context *draw_create( struct pipe_context *pipe )
  {
     struct draw_context *draw = CALLOC_STRUCT( draw_context );
     if (draw == NULL)
        goto fail;
  
 +#if HAVE_LLVM
 +   assert(lp_build_engine);
 +   draw->engine = lp_build_engine;
 +#endif
 +
     if (!draw_init(draw))
        goto fail;
  
 +   draw->pipe = pipe;
 +
     return draw;
  
  fail:
@@@ -103,23 -92,10 +103,23 @@@ boolean draw_init(struct draw_context *
  
  void draw_destroy( struct draw_context *draw )
  {
 +   struct pipe_context *pipe;
 +   int i, j;
 +
     if (!draw)
        return;
  
 +   pipe = draw->pipe;
  
 +   /* free any rasterizer CSOs that we may have created.
 +    */
 +   for (i = 0; i < 2; i++) {
 +      for (j = 0; j < 2; j++) {
 +         if (draw->rasterizer_no_cull[i][j]) {
 +            pipe->delete_rasterizer_state(pipe, draw->rasterizer_no_cull[i][j]);
 +         }
 +      }
 +   }
  
     /* Not so fast -- we're just borrowing this at the moment.
      * 
@@@ -161,17 -137,12 +161,17 @@@ void draw_set_mrd(struct draw_context *
   * This causes the drawing pipeline to be rebuilt.
   */
  void draw_set_rasterizer_state( struct draw_context *draw,
 -                                const struct pipe_rasterizer_state *raster )
 +                                const struct pipe_rasterizer_state *raster,
 +                                void *rast_handle )
  {
 -   draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
 +   if (!draw->suspend_flushing) {
 +      draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
  
 -   draw->rasterizer = raster;
 -   draw->bypass_clipping = draw->driver.bypass_clipping;
 +      draw->rasterizer = raster;
 +      draw->rast_handle = rast_handle;
 +
 +      draw->bypass_clipping = draw->driver.bypass_clipping;
 +   }
  }
  
  
@@@ -456,12 -427,14 +456,14 @@@ void draw_set_render( struct draw_conte
  void
  draw_set_mapped_element_buffer_range( struct draw_context *draw,
                                        unsigned eltSize,
+                                       int eltBias,
                                        unsigned min_index,
                                        unsigned max_index,
                                        const void *elements )
  {
     draw->pt.user.elts = elements;
     draw->pt.user.eltSize = eltSize;
+    draw->pt.user.eltBias = eltBias;
     draw->pt.user.min_index = min_index;
     draw->pt.user.max_index = max_index;
  }
  void
  draw_set_mapped_element_buffer( struct draw_context *draw,
                                  unsigned eltSize,
+                                 int eltBias,
                                  const void *elements )
  {
     draw->pt.user.elts = elements;
     draw->pt.user.eltSize = eltSize;
+    draw->pt.user.eltBias = eltBias;
     draw->pt.user.min_index = 0;
     draw->pt.user.max_index = 0xffffffff;
  }
@@@ -524,37 -499,3 +528,37 @@@ draw_current_shader_position_output(con
        return draw->gs.position_output;
     return draw->vs.position_output;
  }
 +
 +
 +/**
 + * Return a pointer/handle for a driver/CSO rasterizer object which
 + * disabled culling, stippling, unfilled tris, etc.
 + * This is used by some pipeline stages (such as wide_point, aa_line
 + * and aa_point) which convert points/lines into triangles.  In those
 + * cases we don't want to accidentally cull the triangles.
 + *
 + * \param scissor  should the rasterizer state enable scissoring?
 + * \param flatshade  should the rasterizer state use flat shading?
 + * \return  rasterizer CSO handle
 + */
 +void *
 +draw_get_rasterizer_no_cull( struct draw_context *draw,
 +                             boolean scissor,
 +                             boolean flatshade )
 +{
 +   if (!draw->rasterizer_no_cull[scissor][flatshade]) {
 +      /* create now */
 +      struct pipe_context *pipe = draw->pipe;
 +      struct pipe_rasterizer_state rast;
 +
 +      memset(&rast, 0, sizeof(rast));
 +      rast.scissor = scissor;
 +      rast.flatshade = flatshade;
 +      rast.front_winding = PIPE_WINDING_CCW;
 +      rast.gl_rasterization_rules = draw->rasterizer->gl_rasterization_rules;
 +
 +      draw->rasterizer_no_cull[scissor][flatshade] =
 +         pipe->create_rasterizer_state(pipe, &rast);
 +   }
 +   return draw->rasterizer_no_cull[scissor][flatshade];
 +}
index 51767bb214d3f5398e0fc3493782641206a158b0,cfa0ad88d0a65b8a1fa506babeee9127fe34d083..7b41bb48dd317e4219a132b4874b4fe02f5cfadc
@@@ -48,7 -48,7 +48,7 @@@ struct draw_geometry_shader
  struct tgsi_sampler;
  
  
 -struct draw_context *draw_create( void );
 +struct draw_context *draw_create( struct pipe_context *pipe );
  
  void draw_destroy( struct draw_context *draw );
  
@@@ -59,8 -59,7 +59,8 @@@ void draw_set_clip_state( struct draw_c
                            const struct pipe_clip_state *clip );
  
  void draw_set_rasterizer_state( struct draw_context *draw,
 -                                const struct pipe_rasterizer_state *raster );
 +                                const struct pipe_rasterizer_state *raster,
 +                                void *rast_handle );
  
  void draw_set_rasterize_stage( struct draw_context *draw,
                                 struct draw_stage *stage );
@@@ -140,12 -139,14 +140,14 @@@ void draw_set_vertex_elements(struct dr
  void
  draw_set_mapped_element_buffer_range( struct draw_context *draw,
                                        unsigned eltSize,
+                                       int eltBias,
                                        unsigned min_index,
                                        unsigned max_index,
                                        const void *elements );
  
  void draw_set_mapped_element_buffer( struct draw_context *draw,
                                       unsigned eltSize, 
+                                      int eltBias,
                                       const void *elements );
  
  void draw_set_mapped_vertex_buffer(struct draw_context *draw,
@@@ -197,4 -198,11 +199,4 @@@ boolean draw_need_pipeline(const struc
                             const struct pipe_rasterizer_state *rasterizer,
                             unsigned prim );
  
 -#ifdef HAVE_LLVM
 -/*******************************************************************************
 - * LLVM integration
 - */
 -struct draw_context *draw_create_with_llvm(void);
 -#endif
 -
  #endif /* DRAW_CONTEXT_H */
index fa20c8ecc632f677c2e269afef8acab07b5528f5,33b0c196d4ebbd4aca572f741eff83e1de10ab56..0b3c9e69bd53cbd6ce7515df2e563450a0f95aab
@@@ -86,8 -86,6 +86,8 @@@ struct vertex_header 
   */
  struct draw_context
  {
 +   struct pipe_context *pipe;
 +
     /** Drawing/primitive pipeline stages */
     struct {
        struct draw_stage *first;  /**< one of the following */
           const void *elts;
           /** bytes per index (0, 1, 2 or 4) */
           unsigned eltSize;
+          int eltBias;
           unsigned min_index;
           unsigned max_index;
           
  
     double mrd;  /**< minimum resolvable depth value, for polygon offset */
  
 -   /* pipe state that we need: */
 +   /** Current rasterizer state given to us by the driver */
     const struct pipe_rasterizer_state *rasterizer;
 +   /** Driver CSO handle for the current rasterizer state */
 +   void *rast_handle;
 +
 +   /** Rasterizer CSOs without culling/stipple/etc */
 +   void *rasterizer_no_cull[2][2];
 +
     struct pipe_viewport_state viewport;
     boolean identity_viewport;
  
  
  #ifdef HAVE_LLVM
     LLVMExecutionEngineRef engine;
 +   boolean use_llvm;
  #endif
     void *driver_private;
  };
@@@ -365,10 -357,5 +366,10 @@@ void draw_do_flush( struct draw_contex
  
  
  
 +void *
 +draw_get_rasterizer_no_cull( struct draw_context *draw,
 +                             boolean scissor,
 +                             boolean flatshade );
 +
  
  #endif /* DRAW_PRIVATE_H */
index cea186c1bf3e8354fb6dc154bf0b218f859699d5,aa1f7064a3a2c497b5470d4e66d7941c75623b83..b5876bb1bdb5f4facf59e72c22ea2d2f8c1471da
@@@ -111,6 -111,7 +111,7 @@@ draw_pt_arrays(struct draw_context *dra
     frontend->run(frontend, 
                   draw_pt_elt_func(draw),
                   draw_pt_elt_ptr(draw, start),
+                  draw->pt.user.eltBias,
                   count);
  
     frontend->finish( frontend );
@@@ -141,9 -142,7 +142,9 @@@ boolean draw_pt_init( struct draw_conte
        return FALSE;
  
  #if HAVE_LLVM
 -   draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit_llvm( draw );
 +   draw->use_llvm = debug_get_bool_option("DRAW_USE_LLVM", TRUE);
 +   if (draw->use_llvm)
 +      draw->pt.middle.general = draw_pt_fetch_pipeline_or_emit_llvm( draw );
  #else
     draw->pt.middle.general = NULL;
  #endif
@@@ -224,8 -223,11 +225,11 @@@ draw_print_arrays(struct draw_context *
              break;
           default:
              assert(0);
+             return;
           }
-          debug_printf("Element[%u + %u] -> Vertex %u:\n", start, i, ii);
+          ii += draw->pt.user.eltBias;
+          debug_printf("Element[%u + %u] + %i -> Vertex %u:\n", start, i,
+                       draw->pt.user.eltBias, ii);
        }
        else {
           /* non-indexed arrays */
index 12dea9f806c78a8724df9e93982529f0304f4bfb,beddc139964537077c41a21f6cfc7b28e4748748..2af9bdac956daf44b078d63a34c82ab8143bfea6
@@@ -48,6 -48,7 +48,7 @@@ static voi
  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)
      */
     if (indexBuffer) {
        void *mapped_indexes = i915_buffer(indexBuffer)->data;
-       draw_set_mapped_element_buffer_range(draw, indexSize,
+       draw_set_mapped_element_buffer_range(draw, indexSize, indexBias,
                                             min_index,
                                             max_index,
                                             mapped_indexes);
     } else {
-       draw_set_mapped_element_buffer(draw, 0, NULL);
+       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
     }
  
  
     }
  
     if (indexBuffer) {
-       draw_set_mapped_element_buffer(draw, 0, NULL);
+       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
     }
  }
  
  static void
  i915_draw_elements(struct pipe_context *pipe,
                     struct pipe_resource *indexBuffer,
-                    unsigned indexSize,
+                    unsigned indexSize, int indexBias,
                     unsigned prim, unsigned start, unsigned count)
  {
     i915_draw_range_elements(pipe, indexBuffer,
-                             indexSize,
+                             indexSize, indexBias,
                              0, 0xffffffff,
                              prim, start, count);
  }
@@@ -119,7 -120,7 +120,7 @@@ static voi
  i915_draw_arrays(struct pipe_context *pipe,
                   unsigned prim, unsigned start, unsigned count)
  {
-    i915_draw_elements(pipe, NULL, 0, prim, start, count);
+    i915_draw_elements(pipe, NULL, 0, 0, prim, start, count);
  }
  
  
@@@ -174,7 -175,7 +175,7 @@@ i915_create_context(struct pipe_screen 
     /*
      * Create drawing context and plug our rendering stage into it.
      */
 -   i915->draw = draw_create();
 +   i915->draw = draw_create(&i915->base);
     assert(i915->draw);
     if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) {
        draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
index b8e94885f0428b183ad44cf91eeb71df9ed6b316,d441d032d9dc7d94ad496d72381b5a06bcbdd374..4d7b7f181d87445320f45c0365965a44f55e706e
@@@ -122,12 -122,11 +122,12 @@@ nvfx_vbo_static_attrib(struct nvfx_cont
        struct pipe_transfer *transfer;
        struct nouveau_channel* chan = nvfx->screen->base.channel;
        void *map;
 +      float *v;
  
        map  = pipe_buffer_map(&nvfx->pipe, vb->buffer, PIPE_TRANSFER_READ, &transfer);
 -      map += vb->buffer_offset + ve->src_offset;
 +      map = (uint8_t *) map + vb->buffer_offset + ve->src_offset;
  
 -      float *v = map;
 +      v = map;
  
        switch (ncomp) {
        case 4:
@@@ -168,17 -167,17 +168,17 @@@ nvfx_draw_arrays(struct pipe_context *p
  
        nvfx_vbo_set_idxbuf(nvfx, NULL, 0);
        if (nvfx->screen->force_swtnl || !nvfx_state_validate(nvfx)) {
-               nvfx_draw_elements_swtnl(pipe, NULL, 0,
+               nvfx_draw_elements_swtnl(pipe, NULL, 0, 0,
                                             mode, start, count);
                  return;
        }
  
        while (count) {
 -              unsigned vc, nr;
 +              unsigned vc, nr, avail;
  
                nvfx_state_emit(nvfx);
  
 -              unsigned avail = AVAIL_RING(chan);
 +              avail = AVAIL_RING(chan);
                avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
  
                vc = nouveau_vbuf_split(avail, 6, 256,
@@@ -230,11 -229,11 +230,11 @@@ nvfx_draw_elements_u08(struct nvfx_cont
  
        while (count) {
                uint8_t *elts = (uint8_t *)ib + start;
 -              unsigned vc, push, restart = 0;
 +              unsigned vc, push, restart = 0, avail;
  
                nvfx_state_emit(nvfx);
  
 -              unsigned avail = AVAIL_RING(chan);
 +              avail = AVAIL_RING(chan);
                avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
  
                vc = nouveau_vbuf_split(avail, 6, 2,
@@@ -283,11 -282,11 +283,11 @@@ nvfx_draw_elements_u16(struct nvfx_cont
  
        while (count) {
                uint16_t *elts = (uint16_t *)ib + start;
 -              unsigned vc, push, restart = 0;
 +              unsigned vc, push, restart = 0, avail;
  
                nvfx_state_emit(nvfx);
  
 -              unsigned avail = AVAIL_RING(chan);
 +              avail = AVAIL_RING(chan);
                avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
  
                vc = nouveau_vbuf_split(avail, 6, 2,
@@@ -336,11 -335,11 +336,11 @@@ nvfx_draw_elements_u32(struct nvfx_cont
  
        while (count) {
                uint32_t *elts = (uint32_t *)ib + start;
 -              unsigned vc, push, restart = 0;
 +              unsigned vc, push, restart = 0, avail;
  
                nvfx_state_emit(nvfx);
  
 -              unsigned avail = AVAIL_RING(chan);
 +              avail = AVAIL_RING(chan);
                avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
  
                vc = nouveau_vbuf_split(avail, 5, 1,
  
  static void
  nvfx_draw_elements_inline(struct pipe_context *pipe,
-                         struct pipe_resource *ib, unsigned ib_size,
+                         struct pipe_resource *ib,
+                         unsigned ib_size, int ib_bias,
                          unsigned mode, unsigned start, unsigned count)
  {
        struct nvfx_context *nvfx = nvfx_context(pipe);
                return;
        }
  
+       assert(ib_bias == 0);
        switch (ib_size) {
        case 1:
                nvfx_draw_elements_u08(nvfx, map, mode, start, count);
@@@ -414,11 -416,11 +417,11 @@@ nvfx_draw_elements_vbo(struct pipe_cont
        unsigned restart = 0;
  
        while (count) {
 -              unsigned nr, vc;
 +              unsigned nr, vc, avail;
  
                nvfx_state_emit(nvfx);
  
 -              unsigned avail = AVAIL_RING(chan);
 +              avail = AVAIL_RING(chan);
                avail -= 16 + (avail >> 10); /* for the BEGIN_RING_NIs, conservatively assuming one every 1024, plus 16 for safety */
  
                vc = nouveau_vbuf_split(avail, 6, 256,
  
  void
  nvfx_draw_elements(struct pipe_context *pipe,
-                  struct pipe_resource *indexBuffer, unsigned indexSize,
+                  struct pipe_resource *indexBuffer,
+                  unsigned indexSize, int indexBias,
                   unsigned mode, unsigned start, unsigned count)
  {
        struct nvfx_context *nvfx = nvfx_context(pipe);
  
        idxbuf = nvfx_vbo_set_idxbuf(nvfx, indexBuffer, indexSize);
        if (nvfx->screen->force_swtnl || !nvfx_state_validate(nvfx)) {
-               nvfx_draw_elements_swtnl(pipe, indexBuffer, indexSize,
-                                            mode, start, count);
+               nvfx_draw_elements_swtnl(pipe,
+                                        indexBuffer, indexSize, indexBias,
+                                        mode, start, count);
                return;
        }
  
        if (idxbuf) {
                nvfx_draw_elements_vbo(pipe, mode, start, count);
        } else {
-               nvfx_draw_elements_inline(pipe, indexBuffer, indexSize,
+               nvfx_draw_elements_inline(pipe,
+                                         indexBuffer, indexSize, indexBias,
                                          mode, start, count);
        }
  
index a3fd8cc67d8552cf71f4025ef5630acff8d9c543,007f01ace30ef9a7d0bb6c514b4fa080f256b15e..23b61df89cc775703789531430d0426033f5d53d
@@@ -152,9 -152,9 +152,9 @@@ static boolean immd_is_good_idea(struc
          if (!checked[vbi]) {
              vbuf = &r300->vertex_buffer[vbi];
  
 -            if (r300->context.is_resource_referenced(&r300->context,
 -                                                   vbuf->buffer,
 -                                                   0, 0)) {
 +            if (r300_buffer_is_referenced(&r300->context,
 +                                          vbuf->buffer,
 +                                          R300_REF_CS | R300_REF_HW)) {
                  /* It's a very bad idea to map it... */
                  return FALSE;
              }
@@@ -298,6 -298,7 +298,7 @@@ void r500_emit_draw_arrays(struct r300_
  void r500_emit_draw_elements(struct r300_context *r300,
                               struct pipe_resource* indexBuffer,
                               unsigned indexSize,
+                              int indexBias,
                               unsigned minIndex,
                               unsigned maxIndex,
                               unsigned mode,
          return;
      }
  
+     assert(indexBias == 0);
      maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index);
  
      DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n",
@@@ -442,6 -445,7 +445,7 @@@ void r300_emit_draw_arrays(struct r300_
  void r300_emit_draw_elements(struct r300_context *r300,
                               struct pipe_resource* indexBuffer,
                               unsigned indexSize,
+                              int indexBias,
                               unsigned minIndex,
                               unsigned maxIndex,
                               unsigned mode,
                               unsigned count)
  {
      if (!r300->stencil_ref_bf_fallback) {
-         r500_emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
-                                 maxIndex, mode, start, count);
+         r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+                                 minIndex, maxIndex, mode, start, count);
      } else {
          r300_begin_stencil_ref_fallback(r300);
-         r500_emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
-                                 maxIndex, mode, start, count);
+         r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+                                 minIndex, maxIndex, mode, start, count);
          r300_switch_stencil_ref_side(r300);
-         r500_emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
-                                 maxIndex, mode, start, count);
+         r500_emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+                                 minIndex, maxIndex, mode, start, count);
          r300_end_stencil_ref_fallback(r300);
      }
  }
@@@ -528,6 -532,7 +532,7 @@@ static void r300_align_ushort_elts(stru
  void r300_draw_range_elements(struct pipe_context* pipe,
                                struct pipe_resource* indexBuffer,
                                unsigned indexSize,
+                               int indexBias,
                                unsigned minIndex,
                                unsigned maxIndex,
                                unsigned mode,
      u_upload_flush(r300->upload_vb);
      u_upload_flush(r300->upload_ib);
      if (alt_num_verts || count <= 65535) {
-         r300->emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
-                                  maxIndex, mode, start, count);
+         r300->emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+                                  minIndex, maxIndex, mode, start, count);
      } else {
          do {
              short_count = MIN2(count, 65534);
-             r300->emit_draw_elements(r300, indexBuffer, indexSize, minIndex,
-                                       maxIndex, mode, start, short_count);
+             r300->emit_draw_elements(r300, indexBuffer, indexSize, indexBias,
+                                      minIndex, maxIndex,
+                                      mode, start, short_count);
  
              start += short_count;
              count -= short_count;
  /* Simple helpers for context setup. Should probably be moved to util. */
  void r300_draw_elements(struct pipe_context* pipe,
                          struct pipe_resource* indexBuffer,
-                         unsigned indexSize, unsigned mode,
+                         unsigned indexSize, int indexBias, unsigned mode,
                          unsigned start, unsigned count)
  {
      struct r300_context *r300 = r300_context(pipe);
  
-     pipe->draw_range_elements(pipe, indexBuffer, indexSize, 0,
-                               r300->vertex_buffer_max_index,
+     pipe->draw_range_elements(pipe, indexBuffer, indexSize, indexBias,
+                               0, r300->vertex_buffer_max_index,
                                mode, start, count);
  }
  
@@@ -698,7 -704,7 +704,7 @@@ void r300_swtcl_draw_arrays(struct pipe
          draw_set_mapped_vertex_buffer(r300->draw, i, buf);
      }
  
-     draw_set_mapped_element_buffer(r300->draw, 0, NULL);
+     draw_set_mapped_element_buffer(r300->draw, 0, 0, NULL);
  
      draw_arrays(r300->draw, mode, start, count);
  
  void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
                                         struct pipe_resource* indexBuffer,
                                         unsigned indexSize,
+                                        int indexBias,
                                         unsigned minIndex,
                                         unsigned maxIndex,
                                         unsigned mode,
  
      indices = pipe_buffer_map(pipe, indexBuffer,
                                PIPE_TRANSFER_READ, &ib_transfer);
-     draw_set_mapped_element_buffer_range(r300->draw, indexSize,
+     draw_set_mapped_element_buffer_range(r300->draw, indexSize, indexBias,
                                           minIndex, maxIndex, indices);
  
      draw_arrays(r300->draw, mode, start, count);
  
      pipe_buffer_unmap(pipe, indexBuffer,
                      ib_transfer);
-     draw_set_mapped_element_buffer_range(r300->draw, 0, start,
-                                          start + count - 1, NULL);
+     draw_set_mapped_element_buffer_range(r300->draw, 0, 0,
+                                          start, start + count - 1,
+                                          NULL);
  }
  
  /* Object for rendering using Draw. */
index 0981d85929fc64bcde9256c5d6018db186b3bd99,4504bf71fda363e79512cee28833901465c7ddf0..eb71c23195b7b327ba232ba2aea2b02da00e33ba
@@@ -39,6 -39,7 +39,7 @@@ enum pipe_erro
  svga_swtnl_draw_range_elements(struct svga_context *svga,
                                 struct pipe_resource *indexBuffer,
                                 unsigned indexSize,
+                                int indexBias,
                                 unsigned min_index,
                                 unsigned max_index,
                                 unsigned prim, unsigned start, unsigned count)
@@@ -82,7 -83,7 +83,7 @@@
                            &ib_transfer);
  
        draw_set_mapped_element_buffer_range(draw, 
-                                            indexSize, 
+                                            indexSize, indexBias,
                                             min_index,
                                             max_index,
                                             map);
  
     if (indexBuffer) {
        pipe_buffer_unmap(&svga->pipe, indexBuffer, ib_transfer);
-       draw_set_mapped_element_buffer(draw, 0, NULL);
+       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
     }
  
     if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
@@@ -142,7 -143,7 +143,7 @@@ boolean svga_init_swtnl( struct svga_co
     /*
      * Create drawing context and plug our rendering stage into it.
      */
 -   svga->swtnl.draw = draw_create();
 +   svga->swtnl.draw = draw_create(&svga->pipe);
     if (svga->swtnl.draw == NULL)
        goto fail;
  
index ce96b01d9b31837c00bf01792bcc143c23d37a22,a28ad8eebb60542912324ffb51c4176e98fc1305..0889f1a522de389fc784bce0443f24ac5f66fa15
@@@ -137,7 -137,7 +137,7 @@@ st_feedback_draw_vbo(GLcontext *ctx
     assert(draw);
     draw_set_viewport_state(draw, &st->state.viewport);
     draw_set_clip_state(draw, &st->state.clip);
 -   draw_set_rasterizer_state(draw, &st->state.rasterizer);
 +   draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL);
     draw_bind_vertex_shader(draw, st->vp_varient->draw_shader);
     set_feedback_vertex_format(ctx);
  
           map = pipe_buffer_map(pipe, index_buffer_handle,
                                 PIPE_TRANSFER_READ, &ib_transfer);
  
-          draw_set_mapped_element_buffer(draw, indexSize, map);
+          draw_set_mapped_element_buffer(draw, indexSize, 0, map);
        }
        else {
-          draw_set_mapped_element_buffer(draw, indexSize, (void *) ib->ptr);
+          draw_set_mapped_element_buffer(draw, indexSize, 0, (void *) ib->ptr);
         ib_transfer = NULL;
        }
     }
     else {
        /* no index/element buffer */
-       draw_set_mapped_element_buffer(draw, 0, NULL);
+       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
     }
  
  
     }
     if (index_buffer_handle) {
        pipe_buffer_unmap(pipe, index_buffer_handle, ib_transfer);
-       draw_set_mapped_element_buffer(draw, 0, NULL);
+       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
     }
  }